<template>
  <div class="page_root" :key="queryUpdateFlag" data-page-name="工单管理" data-page-identification="f_3d93sqxee7">
    <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip">
      <!-- begin vid_met8bhslls 自定义模板_5x2uqbdvih -->
      <!--            改变根因分析提示-->
      <a-modal :zIndex="1001" :visible="tipState.visible" title="提示" :mask-closable="false" centered @ok="confirmRoot" @cancel="cancelRoot"> 切换根因分析后，已编辑的根因解释将被覆盖 </a-modal>
      <!--            改变根因分析提示-->
      <!--          关闭工单-->
      <a-modal
        :visible="newSopState.sopCloseVisible"
        centered
        @cancel="cancelClose"
        @ok="confirmSopClose"
        destroy-on-close
        width="800px"
        title="关闭"
        :mask-closable="false"
        :ok-button-props="{ loading: newSopState.closeLoading }"
      >
        <!--              如果是sop展示-->
        <div class="no-need-tip" v-if="currentCloseData.tag === 1 && currentCloseData.parentId">
          <ExclamationCircleOutlined style="color: #fab221" />
          请确认是否关闭该工单？ 您可以在勾选建立【剩余SOP子工单】，推进父工单解决； 并行SOP子工单解决人不支持重复建立【剩余SOP子工单】，已建立的将为您过滤；
          并行SOP子工单解决人全部未勾选建立【剩余SOP子工单】，父工单直接进入已解决状态；
        </div>
        <div class="no-need-tip" v-else>
          <ExclamationCircleOutlined style="color: #fab221" />
          请确认是否关闭该工单？请填写备注注明原因
        </div>
        <a-form ref="closeRef" :model="newSopState">
          <a-form-item label="备注" :rules="[{ required: true, message: '请输入备注', trigger: 'blur' }]" name="closeRemark">
            <a-textarea v-model:value="newSopState.closeRemark" :rows="4" />
          </a-form-item>
        </a-form>
        <div class="modal-sop-title" v-if="currentCloseData.tag === 1 && currentCloseData.parentId">剩余SOP</div>
        <div class="modal-table" v-if="currentCloseData.tag === 1 && currentCloseData.parentId">
          <a-table
            :columns="sopColumns"
            :data-source="newSopState.sopTableData"
            rowKey="sopStepId"
            :row-selection="{
                            selectedRowKeys: newSopState.selectedRowKeys,
                            onChange: onSopSelectChange,
                            fixed: true,
                            getCheckboxProps: record => ({
                                disabled: record.disabled // Column configuration not to be checked
                            })
                        }"
            :row-class-name="
                            (_record, index) => (index % 2 === 1 ? 'table-striped-even' : 'table-striped-odd')
                        "
            bordered
            :pagination="false"
          />
        </div>
      </a-modal>
      <!--          关闭工单-->

      <!--          新建sop工单-->
      <a-modal centered v-model:visible="newSopState.sopVisible" :ok-button-props="{ loading: newSopState.sopOkLoading }" :mask-closable="false" width="800px" title="+SOP子工单" @cancel="cancelSop">
        <template #footer>
          <a-space>
            <a-button type="primary" ghost @click="cancelSop">取消</a-button>
            <a-button type="primary" @click="handleDownLoadSopTemplate(currentAddSopRecord)" :loading="downTemplateFileLoading">下载附件模板</a-button>
            <a-button type="primary" @click="confirmSop" :loading="sopSonLoading">保存</a-button>
          </a-space>
        </template>
        <div class="modal-table">
          <a-table
            :columns="sopColumns"
            :data-source="newSopState.sopTableData"
            rowKey="sopStepId"
            :row-selection="{
                            selectedRowKeys: newSopState.selectedRowKeys,
                            onChange: onSopSelectChange,
                            fixed: true,
                            getCheckboxProps: record => ({
                                disabled: record.disabled // Column configuration not to be checked
                            })
                        }"
            bordered
            :pagination="false"
            :row-class-name="
                            (_record, index) => (index % 2 === 1 ? 'table-striped-even' : 'table-striped-odd')
                        "
          >
            <template #bodyCell="{ record, text, column, index }">
              <template v-if="column.dataIndex === 'sequence'">
                <a-input v-model:value="record.sequence" />
              </template>
            </template>
          </a-table>
        </div>
        <div style="margin-top: 16px">
          <a-upload v-model:file-list="newSopState.sopFileList" :multiple="true" :before-upload="handlerSopUpload" @remove="handlerSopRemove" accept=".xlsx, image/*,.docx,, .xls,.mp4">
            <a-button type="primary">
              <upload-outlined />
              上传附件
            </a-button>
          </a-upload>
        </div>
      </a-modal>
      <!--          新建sop工单-->
      <!--          无需解决-->
      <a-modal
        :visible="sonState.noNeedVisible"
        centered
        destroy-on-close
        @cancel="cancelNoNeed"
        @ok="noNeedSaveRoot"
        width="1000px"
        title="无需解决"
        :mask-closable="false"
        :ok-button-props="{ loading: sonState.noNeedLoading }"
      >
        <!--              如果是sop展示-->
        <div class="no-need-tip" v-if="noNeedData.tag === 1 && noNeedData.parentId">
          <ExclamationCircleOutlined style="color: #fab221" />
          请确认是否无需解决该工单？<br />
          您可以在勾选建立【剩余SOP子工单】，推进父工单解决；<br />
          并行SOP子工单解决人不支持重复建立【剩余SOP子工单】，已建立的将为您过滤；<br />
          并行SOP子工单解决人全部未勾选建立【剩余SOP子工单】，父工单直接进入已解决状态；<br />
        </div>
        <div class="no-need-tip" v-else>
          <ExclamationCircleOutlined style="color: #fab221" />
          请确认是否无需解决该工单？请填写根因分析和备注，注明原因。
        </div>
        <div class="no-need-form">
          <a-form :model="rootState" ref="rootRef">
            <a-row :gutter="24">
              <a-col :span="6">
                <a-form-item label="责任方" :rules="[{ required: true, message: '请选择责任方', trigger: 'blur' }]" name="responsibleParty">
                  <a-select
                    allow-clear
                    show-search
                    style="width: 100%"
                    v-model:value="rootState.responsibleParty"
                    :options="rootState.responsiblePartyList"
                    placeholder="请选择"
                    :field-names="{ label: 'itemName', value: 'itemName' }"
                    :filterOption="
                                                (input, option) => {
                                                    return (
                                                        option.itemName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                    )
                                                }
                                            "
                    @focus="getResponsiblePartyList"
                    @change="responsiblePartyChange"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="6">
                <a-form-item label="业务类型" :rules="[{ required: true, message: '请选择业务类型', trigger: 'blur' }]" name="businessType">
                  <a-select
                    allow-clear
                    show-search
                    style="width: 100%"
                    v-model:value="rootState.businessType"
                    :options="rootState.businessTypeList"
                    placeholder="请选择"
                    :field-names="{ label: 'itemName', value: 'itemName' }"
                    :filterOption="
                                                (input, option) => {
                                                    return (
                                                        option.itemName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                    )
                                                }
                                            "
                    @focus="getBusinessTypeList"
                    @change="businessTypeChange"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="根因分析" :labelCol="{ span: 4 }" :wrapperCol="{ span: 20 }" :rules="[{ required: true, message: '请选择根因分析', trigger: 'blur' }]" name="rootCauseClassify">
                  <a-select
                    allow-clear
                    show-search
                    style="width: 100%"
                    v-model:value="rootState.rootCauseClassify"
                    :options="rootState.rootCauseClassifyList"
                    placeholder="请选择"
                    :field-names="{ label: 'itemName', value: 'itemName' }"
                    :filterOption="
                                                (input, option) => {
                                                    return (
                                                        option.itemName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                    )
                                                }
                                            "
                    @focus="getRootCauseClassifyList"
                    @change="rootCauseClassifyChange"
                  />
                </a-form-item>
              </a-col>
            </a-row>
          </a-form>
          <a-form-item label="根因详情">
            <QuillEditor ref="rootQuillEditor" :options="editorOption" class="quill-editor" />
          </a-form-item>
          <a-form ref="noNeedRef" :model="sonState">
            <a-form-item label="备注" :rules="[{ required: true, message: '请输入备注', trigger: 'blur' }]" name="noNeedRemark">
              <a-textarea v-model:value="sonState.noNeedRemark" :rows="4" />
            </a-form-item>
          </a-form>
        </div>
        <template v-if="noNeedData.tag === 1 && noNeedData.parentId">
          <div class="modal-sop-title">剩余SOP</div>
          <div class="modal-table">
            <a-table
              :columns="sopColumns"
              :data-source="newSopState.sopTableData"
              rowKey="sopStepId"
              :row-selection="{
                                selectedRowKeys: newSopState.selectedRowKeys,
                                onChange: onSopSelectChange,
                                fixed: true,
                                getCheckboxProps: record => ({
                                    disabled: record.disabled // Column configuration not to be checked
                                })
                            }"
              bordered
              :pagination="false"
              :row-class-name="
                                (_record, index) => (index % 2 === 1 ? 'table-striped-even' : 'table-striped-odd')
                            "
            />
          </div>
        </template>
      </a-modal>
      <!--          无需解决-->
      <!--          新建/编辑工单-->
      <a-modal
        centered
        v-model:visible="state.addOrEditVisible"
        :title="state.modalTitle"
        @ok="submit"
        @cancel="fatherCancel"
        width="1000px"
        destroy-on-close
        :ok-button-props="{ loading: state.fatherLoading }"
      >
        <div class="form-content">
          <a-form :model="state.modalForm" ref="formRef">
            <a-row>
              <a-col :span="24">
                <a-form-item label="工单标题" :rules="[{ required: true, message: '请输入工单标题', trigger: 'blur' }]" name="content">
                  <a-textarea maxlength="100" show-count placeholder="请输入" v-model:value="state.modalForm.content" />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="工单类型" :rules="[{ required: true, message: '请选择工单类型', trigger: 'blur' }]" name="type">
                  <a-select
                    :options="state.workTypeList"
                    v-model:value="state.modalForm.type"
                    placeholder="请选择"
                    :field-names="{ label: 'label', value: 'value' }"
                    :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                    @change="hanldeTypeChange"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="监控场景">
                  <a-select
                    show-search
                    :options="state.monitorSceneList"
                    :field-names="{ label: 'label', value: 'value' }"
                    :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                    allow-clear
                    v-model:value="state.modalForm.monitorScene"
                    placeholder="请选择"
                    @focus="getMonitorSceneList(false)"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="优先级" :rules="[{ required: true, message: '请选择优先级', trigger: 'blur' }]" name="priority">
                  <a-select
                    :disabled="state.modalForm.type === '产品需求'"
                    v-model:value="state.modalForm.priority"
                    :options="[
                                            {
                                                label: 'p0',
                                                value: 'p0'
                                            },
                                            {
                                                label: 'p1',
                                                value: 'p1'
                                            },
                                            {
                                                label: 'p2',
                                                value: 'p2'
                                            },
                                            {
                                                label: 'p3',
                                                value: 'p3'
                                            }
                                        ]"
                    placeholder="请选择"
                    @change="getSolveTimeByType"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12" v-if="state.modalForm.type !== '产品需求'">
                <a-form-item
                  label="计划解决时长"
                  :rules="[
                                        {
                                            pattern: new RegExp(/^(0(\.5)?|[1-9](\d*)?(\.5)?(\.0)?)$/),
                                            message: '请输入大于0的数字(支持0.5的倍数)',
                                            trigger: 'blur'
                                        }
                                    ]"
                  name="workHours"
                >
                  <a-input-number addon-after="小时" style="width: 100%;" placeholder="请输入" v-model:value="state.modalForm.workHours" @change="getSolveTime" max="1000" />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="计划解决时间" :rules="[{ required: true, message: '请选择计划解决时间', trigger: 'blur' }]" name="endTime">
                  <a-date-picker show-time placeholder="请选择" v-model:value="state.modalForm.endTime" value-format="YYYY-MM-DD HH:mm:ss" />
                </a-form-item>
              </a-col>


              <a-col :span="12">
                <a-form-item label="问题来源" :rules="[{ required: true, message: '请选择问题来源', trigger: 'blur' }]" name="questionSource">
                  <a-select v-model:value="state.modalForm.questionSource" :options="state.wtlyList" placeholder="请选择" />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="所属区域" :rules="[{ required: true, message: '请选择所属区域', trigger: 'blur' }]" name="areaCode">
                  <a-select
                    allow-clear
                    show-search
                    :options="state.areaList"
                    placeholder="请选择"
                    v-model:value="state.modalForm.areaCode"
                    @focus="getAreaList"
                    :field-names="{ label: 'label', value: 'value' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                    @change="areaChange"
                  />
                </a-form-item>
              </a-col>

              <a-col :span="12">
                <a-form-item
                  label="所属客户"
                  :rules="[
                                        {
                                            required: true,
                                            message: '请选择所属客户',
                                            trigger: 'blur'
                                        }
                                    ]"
                  name="customer"
                >
                  <a-select
                    allow-clear
                    show-search
                    :options="state.customList"
                    placeholder="请选择"
                    v-model:value="state.modalForm.customer"
                    @focus="getCustomerList"
                    :field-names="{ label: 'name', value: 'name' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                    @change="customerChange"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="所属项目" :rules="[{ required: true, message: '请选择所属项目', trigger: 'blur' }]" name="projectId">
                  <a-select
                    allow-clear
                    show-search
                    :options="state.projectList"
                    placeholder="请选择"
                    v-model:value="state.modalForm.projectId"
                    :field-names="{ label: 'projectName', value: 'projectId' }"
                    :filter-option="
                                            (input, option) => {
                                                return (
                                                    option.projectName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                )
                                            }
                                        "
                    @focus="getProjectList"
                    @change="projectChange"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="项目阶段">
                  <a-select
                    allow-clear
                    show-search
                    :options="state.milepostList"
                    placeholder="请选择"
                    v-model:value="state.modalForm.milepostId"
                    :field-names="{ label: 'milepostName', value: 'milepostId' }"
                    :filter-option="
                                            (input, option) => {
                                                return (
                                                    option.milepostName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                )
                                            }
                                        "
                    @focus="getMilepostList"
                    @change="milepostChange"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="任务名称">
                  <a-select
                    allow-clear
                    show-search
                    :options="state.taskList"
                    placeholder="请选择"
                    v-model:value="state.modalForm.taskId"
                    :field-names="{ label: 'taskName', value: 'taskId' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.taskName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                    @focus="getTaskList"
                  />
                </a-form-item>
              </a-col>

              <a-col :span="12">
                <a-form-item
                  label="环境"
                  :rules="[
                                        {
                                            // required: currentData.questionSource === '问题转化' ? false : true,
                                            required:false,
                                            message: '请选择环境',
                                            trigger: 'blur'
                                        }
                                    ]"
                  name="environment"
                >
                  <a-select
                    show-search
                    allow-clear
                    :options="state.environmentList"
                    placeholder="请选择"
                    v-model:value="state.modalForm.environment"
                    :field-names="{ label: 'name', value: 'name' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                    @focus="getEnvironmentList"
                    @change="environmentChange"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item
                  label="所属产品"
                  :rules="[
                                        {
                                            // required: currentData.questionSource === '问题转化' ? false : true,
                                            required: false,
                                            message: '请选择所属产品',
                                            trigger: 'blur'
                                        }
                                    ]"
                  name="production"
                >
                  <a-select
                    show-search
                    allow-clear
                    :options="state.productList"
                    placeholder="请选择"
                    v-model:value="state.modalForm.production"
                    @change="productChange"
                    @focus="getProductList"
                    :field-names="{ label: 'name', value: 'name' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                  />
                </a-form-item>
              </a-col>

              <a-col :span="12">
                <a-form-item label="版本">
                  <a-input v-model:value="state.modalForm.version" disabled />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="告警级别">
                  <a-select
                    show-search
                    allow-clear
                    :options="state.warnList"
                    placeholder="请选择"
                    v-model:value="state.modalForm.warningLevel"
                    :field-names="{ label: 'label', value: 'label' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                  />
                </a-form-item>
              </a-col>
            </a-row>
            <div
              class="description-tip"
              v-if="
                                (currentData.status !== '未开始' && currentData.status !== '待分发') &&
                                currentData.status
                            "
            ><ExclamationCircleFilled class="tip-img" /> 解决中的工单不支持编辑问题描述</div
            >
            <a-row
              :style="{
                                pointerEvents:
                                    currentData.status === '未开始' ||
                                    !currentData.status ||
                                    currentData.status === '待分发'
                                        ? 'auto'
                                        : 'none'
                            }"
            >
              <a-col :span="24">
                <a-form-item label="问题描述" :rules="[{ required: true, message: '请输入问题描述', trigger: 'blur' }]" name="qillData">
                  <QuillEditor v-model:content="state.modalForm.qillData" ref="quillEditor" :options="editorOption" class="quill-editor" />
                </a-form-item>
              </a-col>
            </a-row>
                                    <a-row v-if="!currentData.id">
                                        <a-col :span="24">
                                            <a-form-item
                                                label="解决人"
                                                :rules="[{ required: false, message: '请选择解决人', trigger: 'blur' }]"
                                                name="solverList"
                                            >
                                                <a-select
                                                    class="remove-icon"
                                                    show-search
                                                    mode="multiple"
                                                    :options="state.allUser"
                                                    v-model:value="state.modalForm.solverList"
                                                    placeholder="请选择"
                                                    :field-names="{ label: 'name', value: 'name' }"
                                                    :filter-option="
                                                        (input, option) => {
                                                            return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                        }
                                                    "
                                                    @change="fatherSolverChange"
                                                />
                                            </a-form-item>
                                        </a-col>
                                    </a-row>
                                    <!--                      <a-col v-if="taskPeopleList.length > 0">-->
                                    <a-col>
                                        <div style="width: 700px; margin-left: 135px; margin-bottom: 16px">
                                            <a
                                                href="javascript:;"
                                                v-for="(item, num) in taskPeopleList"
                                                @click="handlerAddPeople(item.value, index)"
                                                ><span style="margin: 0 5px">{{ item.value }}</span></a
                                            >
                                        </div>
                                    </a-col>
            <a-col :span="24">
              <a-form-item label="上传附件">
                <a-upload
                  v-model:file-list="state.modalForm.descriptionAttachmentList"
                  :multiple="true"
                  :before-upload="handlerFatherUpload"
                  @remove="handlerFatherRemove"
                  accept=".xlsx, image/*,.docx,, .xls,.mp4"
                >
                  <a-button type="primary">
                    <upload-outlined />
                    上传
                  </a-button>
                </a-upload>
                <span>支持格式：.xlsx, image/*,.docx,, .xls,.mp4</span>
              </a-form-item>
            </a-col>
          </a-form>
        </div>
      </a-modal>
      <!--          新建/编辑工单-->
      <!--          编辑子工单-->
      <a-modal centered v-model:visible="state.editSonVisible" :title="sonState.modalTitle" @ok="submitSon" width="1000px" :ok-button-props="{ loading: state.sonLoading }" @cancel="cancelSon">
        <div class="form-content">
          <a-form :model="state.sonForm" ref="sonRef">
            <a-row>
              <a-col :span="24">
                <a-form-item label="工单标题" :rules="[{ required: true, message: '请输入工单标题', trigger: 'blur' }]" name="content">
                  <a-input maxlength="100" show-count placeholder="请输入" v-model:value="state.sonForm.content" />
                </a-form-item>
              </a-col>
            </a-row>

            <a-row>
              <!--                            <a-col :span="24">-->
              <!--                                <a-form-item-->
              <!--                                    label="计划解决时间"-->
              <!--                                    :rules="[{ required: false, message: '请选择计划解决时间', trigger: 'blur' }]"-->
              <!--                                    name="endTime"-->
              <!--                                >-->
              <!--                                    <a-date-picker-->
              <!--                                        show-time-->
              <!--                                        placeholder="请选择"-->
              <!--                                        v-model:value="state.sonForm.endTime"-->
              <!--                                        value-format="YYYY-MM-DD HH:mm:ss"-->
              <!--                                    />-->
              <!--                                </a-form-item>-->
              <!--                            </a-col>-->

              <a-col :span="24">
                <div
                  class="description-tip"
                  v-if="
                                        (currentData.status !== '未开始' || currentData.status !== '待分发') &&
                                        currentData.status
                                    "
                ><ExclamationCircleFilled class="tip-img" /> 解决中的工单不支持编辑问题描述</div
                >
              </a-col>
            </a-row>
            <a-row>
              <a-col
                :span="24"
                :style="{
                                    pointerEvents:
                                        currentData.status === '未开始' ||
                                        !currentData.status ||
                                        currentData.status === '待分发'
                                            ? 'auto'
                                            : 'none'
                                }"
              >
                <a-form-item label="问题描述" :rules="[{ required: true, message: '请输入问题描述', trigger: 'blur' }]" name="quillData">
                  <QuillEditor ref="sonQuillRef" v-model:content="state.sonForm.quillData" :options="editorOption" class="quill-editor" />
                </a-form-item>
              </a-col>
            </a-row>
            <a-col :span="24">
              <a-form-item label="上传附件">
                <a-upload
                  v-model:file-list="state.sonForm.descriptionAttachmentList"
                  :multiple="true"
                  :before-upload="handlerSonUpload"
                  @remove="handlerSonRemove"
                  accept=".xlsx, image/*,.docx,, .xls,.mp4"
                >
                  <a-button type="primary">
                    <upload-outlined />
                    上传
                  </a-button>
                </a-upload>
                <span>支持格式：.xlsx, image/*,.docx,, .xls,.mp4</span>
              </a-form-item>
            </a-col>
          </a-form>
        </div>
      </a-modal>
      <!--          编辑子工单-->

      <!--          流转变更-->
      <a-modal
        centered
        v-model:visible="newState.circulationVisible"
        title="流转"
        width="520px"
        @ok="confirmCirculation"
        destroy-on-close
        :body-style="{
                    paddingBottom: 0
                }"
        :ok-button-props="{
                    loading: newState.changeStatusLoading
                }"
        @cancel="cancelCirculation"
      >
        <div class="change-status">
          <a-form :model="newState.circulationForm" ref="circulationFormRef">
            <a-row>
              <a-col :span="24">
                <a-form-item label="解决人" :rules="[{ required: true, message: '请选择解决人', trigger: 'blur' }]" name="solverList">
                  <a-select
                    class="remove-icon"
                    show-search
                    :allow-clear="false"
                    mode="multiple"
                    :options="state.allUser"
                    v-model:value="newState.circulationForm.solverList"
                    placeholder="请选择"
                    :field-names="{ label: 'name', value: 'name' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                    @change="changeStatusSolverChange"
                  />
                </a-form-item>
              </a-col>
            </a-row>
          </a-form>
        </div>
      </a-modal>
      <!--          流转变更-->
      <!--          解决中变更-->
      <a-modal
        centered
        v-model:visible="newState.resolvingVisible"
        title="开始解决"
        width="800px"
        destroy-on-close
        :ok-button-props="{
                    loading: newState.changeStatusLoading
                }"
        @cancel="cancelResolving"
      >
        <template #footer>
          <a-space>
            <a-button type="default" @click="cancelResolving">取消</a-button>
            <a-button type="primary" @click="handleDownLoadSopTemplate(currentResolvingData)" :loading="downTemplateFileLoading" v-if="currentResolvingData.tag === 1">下载附件模板</a-button>
            <a-button type="primary" @click="confirmResolving" :loading="newState.changeStatusLoading">确定</a-button>
          </a-space>
        </template>
        <template v-if="currentResolvingData.tag === 1 && !currentResolvingData.parentId">
          <div class="sop-start-tip">
            <ExclamationCircleOutlined style="color: #fab221" />
            请选择执行SOP工单，不选择则不建立SOP子工单，直接开始工单任务。
          </div>
          <div class="modal-table">
            <a-table
              :columns="sopColumns"
              :data-source="newSopState.sopTableData"
              rowKey="sopStepId"
              :row-selection="{
                                selectedRowKeys: newSopState.selectedRowKeys,
                                onChange: onSopSelectChange,
                                fixed: true,
                                getCheckboxProps: record => ({
                                    disabled: record.disabled // Column configuration not to be checked
                                })
                            }"
              :row-class-name="
                                (_record, index) => (index % 2 === 1 ? 'table-striped-even' : 'table-striped-odd')
                            "
              bordered
              :pagination="false"
            >
              <template #bodyCell="{ record, text, column, index }">
                <template v-if="column.dataIndex === 'sequence'">
                  <a-input v-model:value="record.sequence" />
                </template>
              </template>
            </a-table>
          </div>
        </template>
        <div class="change-status-tip" v-else> 确定开始处理工单吗 </div>
        <!--              如果是sop父工单展示这个-->
      </a-modal>
      <!--          解决中变更-->
      <!--          已解决变更-->
      <a-modal
        centered
        v-model:visible="newState.resolvedVisible"
        title="已解决"
        width="1000px"
        :body-style="{
                    paddingBottom: 0,
                    maxHeight: '800px',
                    overflowY: 'auto'
                }"
        destroy-on-close
        :ok-button-props="{
                    loading: newState.changeStatusLoading
                }"
        @cancel="cancelResolved"
      >
        <template #footer>
          <a-space>
            <a-button type="default" @click="cancelResolved">取消</a-button>
            <a-button v-if="resolvedData.tag === 1" type="primary" @click="handleDownLoadSopTemplate(resolvedData)" :loading="downTemplateFileLoading">下载附件模板</a-button>
            <a-button type="primary" @click="saveRoot" :loading="newState.changeStatusLoading">确定</a-button>
          </a-space>
        </template>
        <div class="change-status">
          <template v-if="resolvedData.tag === 1">
            <div class="change-status-resolved">
              <div class="resolved-div">
                <ExclamationCircleOutlined style="color: #fab221; margin-top: 3px" />
                <div>
                  请确认是否完成该工单？如该步骤包含附件请上传；<br />
                  您可以在勾选建立【剩余SOP子工单】，推进父工单解决；<br />
                  并行SOP子工单解决人不支持重复建立【剩余SOP子工单】，已建立的将为您过滤；<br />
                  并行SOP子工单解决人全部未勾选建立【剩余SOP子工单】，父工单直接进入已解决状态；<br />
                </div>
              </div>
              <div class="upload-file">
                <a-upload
                  v-model:file-list="newState.resolvedForm.attachmentList"
                  :multiple="true"
                  :before-upload="handlerResolvedUpload"
                  @remove="handlerResolvedRemove"
                  accept=".xlsx, image/*,.docx,, .xls,.mp4"
                >
                  <a-button type="primary" ghost style="background: rgba(56, 117, 255, 0.1)">
                    <upload-outlined />
                    上传附件
                  </a-button>
                </a-upload>
              </div>
            </div>
            <div class="modal-table" style="margin-bottom: 16px">
              <a-table
                :columns="sopColumns"
                :data-source="newSopState.solvedSOPList"
                bordered
                :pagination="false"
                :row-class-name="
                                    (_record, index) => (index % 2 === 1 ? 'table-striped-even' : 'table-striped-odd')
                                "
              />
            </div>
          </template>
          <template v-if="resolvedData.tag !== 1"> </template>

          <template v-if="!resolvedData.parentId">
            <a-form :model="rootState" ref="rootRef">
              <a-row :gutter="24">
                <a-col :span="6">
                  <a-form-item label="责任方" :labelCol="{ span: 8 }" :wrapperCol="{ span: 16 }" :rules="[{ required: true, message: '请选择责任方', trigger: 'blur' }]" name="responsibleParty">
                    <a-select
                      allow-clear
                      show-search
                      style="width: 100%"
                      v-model:value="rootState.responsibleParty"
                      :options="rootState.responsiblePartyList"
                      placeholder="请选择"
                      :field-names="{ label: 'itemName', value: 'itemName' }"
                      :filterOption="
                                                (input, option) => {
                                                    return (
                                                        option.itemName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                    )
                                                }
                                            "
                      @focus="getResponsiblePartyList"
                      @change="responsiblePartyChange"
                    />
                  </a-form-item>
                </a-col>
                <a-col :span="6">
                  <a-form-item label="业务类型" :labelCol="{ span: 8 }" :wrapperCol="{ span: 16 }" :rules="[{ required: true, message: '请选择业务类型', trigger: 'blur' }]" name="businessType">
                    <a-select
                      allow-clear
                      show-search
                      style="width: 100%"
                      v-model:value="rootState.businessType"
                      :options="rootState.businessTypeList"
                      placeholder="请选择"
                      :field-names="{ label: 'itemName', value: 'itemName' }"
                      :filterOption="
                                                (input, option) => {
                                                    return (
                                                        option.itemName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                    )
                                                }
                                            "
                      @focus="getBusinessTypeList"
                      @change="businessTypeChange"
                    />
                  </a-form-item>
                </a-col>
                <a-col :span="12">
                  <a-form-item label="根因分析" :labelCol="{ span: 4 }" :wrapperCol="{ span: 20 }" :rules="[{ required: true, message: '请选择根因分析', trigger: 'blur' }]" name="rootCauseClassify">
                    <a-select
                      allow-clear
                      show-search
                      style="width: 100%"
                      v-model:value="rootState.rootCauseClassify"
                      :options="rootState.rootCauseClassifyList"
                      placeholder="请选择"
                      :field-names="{ label: 'itemName', value: 'itemName' }"
                      :filterOption="
                                                (input, option) => {
                                                    return (
                                                        option.itemName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                    )
                                                }
                                            "
                      @focus="getRootCauseClassifyList"
                      @change="rootCauseClassifyChange"
                    />
                  </a-form-item>
                </a-col>
              </a-row>
            </a-form>
            <a-form-item label="根因详情">
              <QuillEditor ref="rootQuillEditor" :options="editorOption" class="quill-editor" />
            </a-form-item>
          </template>

          <a-form :model="newState.resolvedForm" ref="resolvedFormRef" style="margin-top: 16px">
            <a-row>
              <a-col :span="24">
                <a-form-item label="解决方案详述" :rules="newRules.solutionDetail" name="solutionDetail">
                  <QuillEditor ref="resolvedQuillRef" :options="editorOption" class="quill-editor" v-model:content="newState.resolvedForm.solutionDetail"
                  /></a-form-item>
              </a-col>
            </a-row>
          </a-form>
          <template v-if="resolvedData.tag === 1 && resolvedData.parentId">
            <div class="modal-sop-title">剩余SOP工单</div>
            <div class="modal-table">
              <a-table
                :columns="sopColumns"
                :data-source="newSopState.sopTableData"
                rowKey="sopStepId"
                :row-selection="{
                                    selectedRowKeys: newSopState.selectedRowKeys,
                                    onChange: onSopSelectChange,
                                    fixed: true,
                                    getCheckboxProps: record => ({
                                        disabled: record.disabled // Column configuration not to be checked
                                    })
                                }"
                :row-class-name="
                                    (_record, index) => (index % 2 === 1 ? 'table-striped-even' : 'table-striped-odd')
                                "
                bordered
                :pagination="false"
              />
            </div>
          </template>
        </div>
      </a-modal>
      <!--          已解决变更-->

      <!--          删除-->
      <a-modal centered v-model:visible="state.deleteVisible" title="删除" @ok="handleDelete" :ok-button-props="{ loading: state.deleteLoading }">
        <!--                请确认是否删除该工单任务，如该工单建立了子工单请先对子工单进行解决后在进行删除操作。-->
        <a-form ref="deleteRef" :model="sonState">
          <a-form-item label="备注" :rules="[{ required: true, message: '请输入备注', trigger: 'blur' }]" name="deleteRemark">
            <a-textarea v-model:value="sonState.deleteRemark" :rows="4" />
          </a-form-item>
        </a-form>
      </a-modal>
      <!--          删除-->
      <div class="top-search">
        <div class="top-left">
          <a-form :model="state.filter">
            <a-row justify="space-between">
              <a-col :span="5">
                <a-form-item label="工单标题" :labelCol="{ span: 7 }" :wrapperCol="{ span: 17 }">
                  <a-input placeholder="请输入" v-model:value="state.filter.keyWords" />
                </a-form-item>
              </a-col>
              <a-col :span="5">
                <a-form-item label="工单编号" :labelCol="{ span: 6 }" :wrapperCol="{ span: 18 }">
                  <a-input placeholder="请输入" v-model:value="state.filter.number" />
                </a-form-item>
              </a-col>
              <a-col :span="5">
                <a-form-item label="工单类型" :labelCol="{ span: 6 }" :wrapperCol="{ span: 18 }">
                  <a-select
                    v-model:value="state.filter.type"
                    :options="state.workTypeList"
                    show-search
                    allow-clear
                    placeholder="请选择"
                    :field-names="{ label: 'label', value: 'value' }"
                    :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                    @change="handleSearchTypeChange"
                  />
                </a-form-item>
              </a-col>

              <a-col :span="5">
                <a-form-item label="监控场景" :labelCol="{ span: 6 }" :wrapperCol="{ span: 18 }">
                  <a-select
                    v-model:value="state.filter.monitorScene"
                    :options="state.monitorSceneList"
                    show-search
                    allow-clear
                    placeholder="请选择"
                    :field-names="{ label: 'label', value: 'value' }"
                    :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                    @focus="getMonitorSceneList(true)"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="4">
                <a-form-item label="优先级" :labelCol="{ span: 7 }" :wrapperCol="{ span: 17 }">
                  <a-select
                    v-model:value="state.filter.priority"
                    :options="[
                                            {
                                                label: 'p0',
                                                value: 'p0'
                                            },
                                            {
                                                label: 'p1',
                                                value: 'p1'
                                            },
                                            {
                                                label: 'p2',
                                                value: 'p2'
                                            },
                                            {
                                                label: 'p3',
                                                value: 'p3'
                                            }
                                        ]"
                    allow-clear
                    placeholder="请选择"
                  />
                </a-form-item>
              </a-col>
            </a-row>
            <a-row justify="space-between" v-if="filterExpand">
              <a-col :span="5">
                <a-form-item label="项目" :labelCol="{ span: 7 }" :wrapperCol="{ span: 17 }">
                  <a-tree-select
                    v-model:value="state.filter.factoryCode"
                    show-search
                    style="width: 100%"
                    placeholder="请选择"
                    allow-clear
                    :tree-data="state.treeData"
                    :fieldNames="{
                                            children: 'children',
                                            label: 'nodeName',
                                            value: 'nodeCode',
                                            key: 'nodeCode'
                                        }"
                    treeDefaultExpandAll
                    :filterTreeNode="
                                            (inputValue, treeNode) => {
                                                return (
                                                    treeNode.nodeName.toLowerCase().indexOf(inputValue.toLowerCase()) >=
                                                    0
                                                )
                                            }
                                        "
                    :max-tag-count="1"
                    @focus="getTreeData"
                    @change="handleTreeChange"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="5">
                <a-form-item label="问题来源" :labelCol="{ span: 6 }" :wrapperCol="{ span: 18 }">
                  <a-select
                    v-model:value="state.filter.questionSource"
                    :options="state.wtlyList"
                    show-search
                    allow-clear
                    placeholder="请选择"
                    :field-names="{ label: 'label', value: 'value' }"
                    :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                  />
                </a-form-item>
              </a-col>
              <a-col :span="5">
                <a-form-item label="产品" :labelCol="{ span: 6 }" :wrapperCol="{ span: 18 }">
                  <a-select
                    show-search
                    v-model:value="state.filter.production"
                    :options="state.productList"
                    allow-clear
                    placeholder="请选择"
                    @focus="getProductList"
                    :field-names="{ label: 'name', value: 'name' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                  />
                </a-form-item>
              </a-col>

              <a-col :span="5">
                <a-form-item label="创建时间" :labelCol="{ span: 6 }" :wrapperCol="{ span: 18 }">
                  <a-range-picker v-model:value="state.filter.createdTimeList" value-format="YYYY-MM-DD" />
                </a-form-item>
              </a-col>
              <a-col :span="4">
                <a-form-item label="环境" :labelCol="{ span: 7 }" :wrapperCol="{ span: 17 }">
                  <a-select
                    v-model:value="state.filter.environment"
                    :options="state.searchEnvironmentList"
                    show-search
                    allow-clear
                    placeholder="请选择"
                    :field-names="{ label: 'name', value: 'name' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                    @focus="getSearchEnvironmentList"
                  />
                </a-form-item>
              </a-col>
            </a-row>
            <!--                        <a-row justify="space-between">-->
            <a-row v-if="filterExpand">
              <a-col :span="5">
                <a-form-item :labelCol="{ span: 7 }" :wrapperCol="{ span: 17 }" label="创建人(owner)">
                  <a-select
                    show-search
                    allow-clear
                    :options="state.allUser"
                    v-model:value="state.filter.createdByName"
                    placeholder="请选择"
                    :field-names="{ label: 'name', value: 'name' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                  />
                </a-form-item>
              </a-col>
              <a-col :span="5">
                <a-form-item :labelCol="{ span: 6 }" :wrapperCol="{ span: 18 }" label="解决人">
                  <a-select
                    show-search
                    allow-clear
                    :options="state.allUser"
                    v-model:value="state.filter.solverName"
                    placeholder="请选择"
                    :field-names="{ label: 'name', value: 'name' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                  />
                </a-form-item>
              </a-col>
              <a-col :span="5">
                <a-form-item :labelCol="{ span: 6 }" :wrapperCol="{ span: 18 }" label="项目经理">
                  <a-select
                    show-search
                    allow-clear
                    :options="state.pmNameList"
                    v-model:value="state.filter.pmName"
                    placeholder="请选择"
                    :field-names="{ label: 'label', value: 'label' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                  />
                </a-form-item>
              </a-col>
              <a-col :span="5">
                <a-form-item :labelCol="{ span: 6 }" :wrapperCol="{ span: 18 }" label="PMO">
                  <a-select
                    show-search
                    allow-clear
                    :options="state.pmoList"
                    v-model:value="state.filter.pmoName"
                    placeholder="请选择"
                    :field-names="{ label: 'label', value: 'label' }"
                    :filter-option="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                  />
                </a-form-item>
              </a-col>

              <a-col :span="4">
                <a-form-item label="是否超时" :labelCol="{ span: 7 }" :wrapperCol="{ span: 17 }">
                  <a-select
                    v-model:value="state.filter.timeout"
                    :options="[
                                            {
                                                label: '是',
                                                value: '是'
                                            },
                                            {
                                                label: '否',
                                                value: '否'
                                            }
                                        ]"
                    show-search
                    allow-clear
                    placeholder="请选择"
                    :field-names="{ label: 'label', value: 'value' }"
                    :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                  />
                </a-form-item>
              </a-col>
            </a-row>
            <a-row>
              <a-col :span="5">
                <a-form-item label="根因归类" :labelCol="{ span: 7 }" :wrapperCol="{ span: 17 }">
                  <a-tree-select
                    v-model:value="state.filter.rootCauseClassify"
                    show-search
                    style="width: 100%"
                    placeholder="请选择"
                    allow-clear
                    treeDefaultExpandAll
                    :tree-data="state.tagList"
                    :fieldNames="{
                                            children: 'children',
                                            label: 'itemName',
                                            value: 'itemCode',
                                            key: 'itemCode'
                                        }"
                    :filterTreeNode="
                                            (inputValue, treeNode) => {
                                                return (
                                                    treeNode.itemName.toLowerCase().indexOf(inputValue.toLowerCase()) >=
                                                    0
                                                )
                                            }
                                        "
                    :max-tag-count="1"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="4" offset="15" style="display: flex; justify-content: end; align-items: start">
                <a-space>
                  <div @click="toggleFilterCollapse" class="toggle-div">
                    <div style="color: #3875ff; cursor: pointer">{{
                        filterExpand ? '收起' : '展开'
                      }}</div>
                    <DoubleLeftOutlined v-if="filterExpand" class="active-icon" />
                    <DoubleRightOutlined v-else class="active-icon" />
                  </div>
                  <a-button type="primary" @click="getData(true)">查询</a-button>
                  <a-button type="primary" ghost @click="resetData">重置</a-button>
                </a-space>
              </a-col>
            </a-row>
          </a-form>
        </div>
      </div>

      <div class="main Page3000001111">
        <a-spin v-model:spinning="dataLoading" tip="加载中">
          <a-tabs v-model:activeKey="activeKey" @change="getData">
            <a-tab-pane key="我的关注" tab="我的关注" />
            <a-tab-pane key="未开始" tab="未开始" />
            <a-tab-pane key="解决中" tab="解决中" />
            <a-tab-pane key="已解决" tab="已解决" />
            <a-tab-pane key="无需解决" tab="无需解决" />
            <a-tab-pane key="已关闭" tab="已关闭" />
            <a-tab-pane key="待分发" tab="待分发" />
            <a-tab-pane key="" tab="全部工单" />

            <!--                        <a-tab-pane key="已回访" tab="已回访" />-->
          </a-tabs>
          <div class="main-title">
            <div class="top-tip"><ExclamationCircleFilled class="tip-img" /> 解决人接收流转的工单后，如距离计划解决时间较近，请及时联系创建人编辑调整，避免工单延期对自己造成影响</div>
            <a-space>
              <a-form-item label="排序" style="margin: 0">
                <a-select style="width: 150px" :options="state.sortList" v-model:value="state.sort" @change="getData" allow-clear />
              </a-form-item>
              <a-button type="primary" @click="handleAdd" v-permission="'3000001145_vid_g6o6reob1t'">新建</a-button>
              <a-button type="primary" @click="handleExport" :loading="exportLoading">导出</a-button>
              <a-button type="primary" @click="handleExpandAll" v-if="!newState.isExpandAll">全部展开</a-button>
              <a-button type="primary" @click="handleCollapseAll" v-else>全部折叠</a-button>
              <a-radio-group v-model:value="viewType" button-style="solid" @change="viewTypeChange">
                <a-radio-button value="卡片展示">卡片展示</a-radio-button>
                <a-radio-button value="表格展示">表格展示</a-radio-button>
              </a-radio-group>
            </a-space>
          </div>
          <div class="gd-scroll-wapper" v-if="viewType==='卡片展示'">
            <div class="gd-scroll-bar" v-if=" state.dataList.length>5">
              <div
                class="gd-bar-item ceycle"
                :class="{
                      'item-open' :isActive(item.id),
                      'status-all' : state.filter.status == '' && !dataLoading,
                      ['status-'+item.status] :1,
                      'ceycle0':/(p0|P0)/i.test(item.priority),
                      'ceycle1':/(p1|P1)/i.test(item.priority),
                      'ceycle2':/(p2|P2)/i.test(item.priority),
                      'ceycle3':/(p3|P3)/i.test(item.priority),
                   }"
                v-for="(item, index) in state.dataList"
                :key="index+'scroll-bar'"
              >
              </div>
            </div>
            <div class="gd-scroll">
              <div class="gd-item" v-for="(item, index) in state.dataList">
                <a-collapse :bordered="false" expandIconPosition="right" v-model:activeKey="state.collapseKey">
                  <template #expandIcon="{ isActive }"> </template>
                  <a-collapse-panel :key="item.id">
                    <template #header>
                      <div class="collapse-title s-bg-jb" :class="getClassStatus(item.status)">
                        <div class="timeout" v-if="item.timeout === '是'">已超时</div>
                        <div class="collapse-title-left">
                          <div class="collapse-title-left-top left-flex">
                            <div v-if="/(p0|P0)/i.test(item.priority)" class="ceycle ceycle0">P0</div>
                            <div v-if="/(p1|P1)/i.test(item.priority)" class="ceycle ceycle1">P1</div>
                            <div v-if="/(p2|P2)/i.test(item.priority)" class="ceycle ceycle2">P2</div>
                            <div v-if="/(p3|P3)/i.test(item.priority)" class="ceycle ceycle3">P3</div>
                            <div v-if="item.questionSource === '400'" class="ph-icon">400</div>
                            <div v-if="item.questionSource === '现场反馈'" class="xc-icon">现场反馈</div>
                            <div v-if="item.questionSource === '系统自检'" class="zj-icon">系统自检</div>
                            <div v-if="item.questionSource === '问题转化'" class="zj-icon">问题转化</div>
                          </div>
                          <div class="collapse-title-left-bottom left-flex" :class="getClassStatus(item.status)">
                            <div class="status-txt s-bg-color" :class="getClassStatus(item.status)">{{ item.status }}</div>
                            <div class="ceycle status-progress s-color s-bg-fff" :class="getClassStatus(item.status)">{{ item.progress }}</div>
                          </div>
                        </div>
                        <div class="father-right">
                          <div class="father-left">
                            <div class="father-title" :class=" { 'tit-kuo':item.tag === 1 || item.factoyName && item.factoyName.indexOf('【') === 0}" :title="item.content">
                              <span
                                style="
                                  border-right: 1px solid #d9d9d9;
                                  padding-right: 8px;
                                  margin-right: 5px;
                              "
                              >
                                <span v-if="item.tag === 1">【SOP工单】</span>
                                {{ item.factoyName }}</span
                              >
                              <span class="under-line" @click.stop="handleDetail(item.id)">{{   item.content  }}</span>
                            </div>
                            <div class="father-bottom">
                              <div class="father-bottom-left">
                                <div class="border-div">
                                  <span class="collapse-title-font">创建时间：</span>
                                  <span class="collapse-content-font">{{
                                      item.createdTime
                                    }}</span>
                                  <div class="border-line"></div>
                                </div>
                                <div class="border-div">
                                  <span class="collapse-title-font">创建人(owner)：</span>
                                  <span class="collapse-content-font">{{
                                      item.createdBy
                                    }}</span>
                                  <div class="border-line"></div>
                                </div>

                                <div class="border-div max-length" v-if="item.solver">
                                  <span class="collapse-title-font">解决人：</span>
                                  <span class="collapse-content-font" :title="item.solver">{{ item.solver || "-" }}</span>
                                </div>

                                <div class="border-div max-length" :title="item.monitorSceneName" v-if=" item.monitorSceneName ">
                                  <span class="collapse-title-font">监控场景：</span>
                                  <span class="collapse-content-font">{{  item.monitorSceneName || "-" }}</span>
                                  <div class="border-line"></div>
                                </div>

                              </div>
                            </div>
                          </div>
                          <div class="father-last">
                            <div class="border-div" style="height: 18px">
                              <span class="collapse-title-font">工单类型：</span>
                              <span class="collapse-content-font">{{
                                  item.type
                                }}</span>
                            </div>
                            <div class="last-left" @click.stop="onClick">
                              <div class="last-top-btn">


                                <a-button type="primary" ghost size="small" class="btn-item" :disabled="isCloseDisabled(item)" @click="handlerClose(item)">关闭 </a-button>
                                <template v-if="['已解决', '无需解决','已关闭'].includes(item.status)">
                                  <a-popconfirm title="请确认是否重新打开工单？" @confirm="handlerReOpen(item)">
                                    <a-button type="primary" ghost size="small" :disabled="!item.myCreated" class="btn-item">重新打开</a-button>
                                  </a-popconfirm>
                                </template>
                                <template v-else>
                                  <a-button type="primary" ghost size="small" class="btn-item" @click="showResolving(item)" :disabled="isResolvingDisabled(item)">开始解决</a-button>
                                </template>
                              </div>
                              <div class="last-bottom-btn">
                                <a-button type="primary" ghost size="small" class="btn-item" @click="showNoNeed(item)" :disabled="isNoNeedSolveDisabled(item)">无需解决</a-button>
                                <a-button type="primary" ghost size="small" class="btn-item" @click="showResolved(item)" :disabled="isResolvedDisabled(item)">已解决 </a-button>
                                <a-button type="primary" size="small" ghost @click="handleFollow(item)" :loading="item.followLoadng"
                                ><StarFilled :style="{ color: item.follow ? '#FF9800' : '#c1c1c1' }" />{{item.follow?'已关注':'关注'}}
                                </a-button>

                              </div>
                            </div>
                            <div class="last-right" @click.stop="onClick">
                              <a-dropdown>
                                <a class="ant-dropdown-link" @click.prevent>
                                  更多
                                  <DownOutlined />
                                </a>
                                <template #overlay>
                                  <a-menu>
                                    <a-menu-item>
                                      <a-button type="link"  size="small" class="btn-item" @click="showCirculation(item)" :disabled="isCirculationDisabled(item)">流转 </a-button>
                                    </a-menu-item>
                                    <a-menu-item>
                                      <a-button type="link"  size="small" class="btn-item" @click="handleEdit(item)" :disabled="isEditDisabled(item)">编辑 </a-button>
                                    </a-menu-item>
                                    <a-menu-item
                                      v-if="
                                            (
                                                (item.status === '未开始' ||
                                                    item.status === '待分发') &&
                                                item.myCreated
                                            )
                                        "
                                    >
                                      <a-button type="link"  size="small" class="btn-item" @click="toDelete(item)">删除 </a-button>
                                    </a-menu-item>
                                    <a-menu-item v-permission="'3000001145_vid_zkfzrjxdj7'">
                                      <a-popconfirm title="请确认是否提醒该工单相关人员？" @confirm="toRmind(item.id)" :disabled="!item.pmoOrNot">
                                        <a-button type="link"  size="small" class="btn-item" :disabled="!item.pmoOrNot">催办 </a-button>
                                      </a-popconfirm>
                                    </a-menu-item>

                                  </a-menu>
                                </template>
                              </a-dropdown>
                            </div>

                            <div class="last-right detail" >
                              <a class="ant-dropdown-link" @click="handleDetail(item.id)">
                                详情
                                <RightOutlined :style="{fontSize: '10px'}" />
                              </a>
                            </div>

                            <div @click.stop="toggleCollapse(item.id)" class="toggle-div last-right detail">
                              <span style="color: #3875ff; cursor: pointer">{{
                                  isActive(item.id) ? '收起' : '展开'
                                }}</span>
                              <DoubleLeftOutlined :style="{fontSize: '10px'}" v-if="isActive(item.id)" class="active-icon" />
                              <DoubleRightOutlined :style="{fontSize: '10px'}" v-else class="active-icon" />
                            </div>
                          </div>
                        </div>
                      </div>
                    </template>
                    <!--                           列表父工单-->
                    <div class="item-inner">
                      <div class="item-content item-content1">
                        <div class="inner">
                          <div class="inner-title">工单编号：</div>
                          <div class="inner-msg" :title="item.number">{{ item.number }}</div>
                        </div>
                        <div class="inner">
                          <div class="inner-title">所属任务：</div>
                          <div class="inner-msg" :title="item.taskName">{{ item.taskName }}</div>
                        </div>

                        <div class="inner">
                          <div class="inner-title">PMO：</div>
                          <div class="inner-msg">{{ item.pmo }}</div>
                        </div>
                      </div>
                      <div class="item-content item-content2">
                        <div class="inner">
                          <div class="inner-title">所属区域：</div>
                          <div class="inner-msg" :title="item.areaName">{{ item.areaName }}</div>
                        </div>
                        <div class="inner">
                          <div class="inner-title">所属环境：</div>
                          <div class="inner-msg">{{ item.environment }}</div>
                        </div>

                        <div class="inner">
                          <div class="inner-title">计划完成时间：</div>
                          <div class="inner-msg">{{ item.endTime }}</div>
                        </div>
                      </div>
                      <div class="item-content item-content3">
                        <div class="inner">
                          <div class="inner-title">所属客户：</div>
                          <div class="inner-msg" :title="item.customer">{{ item.customer }}</div>
                        </div>
                        <div class="inner">
                          <div class="inner-title">所属产品：</div>
                          <div class="inner-msg" :item="item.production">{{
                              item.production
                            }}</div>
                        </div>

                        <div class="inner">
                          <div class="inner-title">实际完成时间：</div>
                          <div class="inner-msg">{{ item.finishTime }}</div>
                        </div>
                      </div>
                      <div class="item-content item-content4">
                        <div class="inner">
                          <div class="inner-title">所属项目：</div>
                          <div class="inner-msg" :title="item.projectName">{{
                              item.projectName
                            }}</div>
                        </div>
                        <div class="inner">
                          <div class="inner-title">版本：</div>
                          <div class="inner-msg" :title="item.version">{{ item.version }}</div>
                        </div>
                      </div>
                      <div class="item-content item-content5">
                        <div class="inner">
                          <div class="inner-title">项目阶段：</div>
                          <div class="inner-msg" :title="item.milepostName">{{
                              item.milepostName
                            }}</div>
                        </div>
                        <div class="inner">
                          <div class="inner-title">项目经理：</div>
                          <div class="inner-msg">{{ item.pmName }}</div>
                        </div>
                        <div></div>
                        <div></div>
                      </div>
                    </div>

                    <!--                           列表父工单-->
                  </a-collapse-panel>
                </a-collapse>
              </div>
            </div>
          </div>
          <div v-else class="gd-table-box">
          <a-table :pagination="false" :columns="gdColumns" :data-source="state.dataList" bordered :scroll="{y:state.tableHeight}"  @resizeColumn="handleResizeColumn">
            <template #headerCell="{ column, title }">
              <template v-if="title === '操作'">
                <div style="display: flex; align-items: center; justify-content: center">{{
                    title
                  }}</div>
              </template>
            </template>
            <template #bodyCell="{ column, record }">
              <template v-if="column.dataIndex === 'content'">

<div class="table-gd-name">
  <div class="timeout-table" v-if="record.timeout === '是'">已超时</div>
 <div :class=" { 'tit-kuo':record.tag === 1 || record.factoyName && record.factoyName.indexOf('【') === 0}"> {{record.factoyName}}</div> <a-divider type="vertical" style="color: #d9d9d9;margin: 0" ></a-divider> <div class="under-line ellipsis-div" :title="record.content" @click="handleDetail(record.id)">{{record.content}}</div>
</div>
              </template>
              <template v-if="column.dataIndex==='status'">
                <div
                  class="status-tag"
                  title="任务状态"
                  :style="getStatusColor(record.status)"
                >{{ record.status || '暂无' }}</div
                >
              </template>
              <template v-if="column.dataIndex === 'operation'">
                <a-space :size="0">
                  <a-button type="link"  size="small"  class="btn-item" :disabled="isCloseDisabled(record)" @click="handlerClose(record)">关闭 </a-button>
                  <template v-if="['已解决', '无需解决','已关闭'].includes(record.status)">
                    <a-popconfirm title="请确认是否重新打开工单？" @confirm="handlerReOpen(record)">
                      <a-button type="link"  size="small" class="btn-item" :disabled="!record.myCreated">重新打开</a-button>
                    </a-popconfirm>
                  </template>
                  <template v-else>
                    <a-button type="link"  size="small" class="btn-item" @click="showResolving(record)" :disabled="isResolvingDisabled(record)">开始解决</a-button>
                  </template>
<!--                  <template>-->
                    <a-button type="link"  size="small" class="btn-item" @click="showNoNeed(record)" :disabled="isNoNeedSolveDisabled(record)">无需解决</a-button>
                    <a-button type="link"  size="small" class="btn-item" @click="showResolved(record)" :disabled="isResolvedDisabled(record)">已解决 </a-button>
                    <a-button type="primary" ghost size="small"  @click="handleFollow(record)" :loading="record.followLoadng" style="margin-right: 7px"
                    ><StarFilled :style="{ color: record.follow ? '#FF9800' : '#c1c1c1' }" />{{record.follow?'已关注':'关注'}}
                    </a-button>
<!--                  </template>-->
                  <a-dropdown >
                    <a class="ant-dropdown-link" @click.prevent>
                      更多
                      <DownOutlined />
                    </a>
                    <template #overlay>
                      <a-menu>
                        <a-menu-item>
                          <a-button type="link"  size="small" class="btn-item" @click="showCirculation(record)" :disabled="isCirculationDisabled(record)">流转 </a-button>
                        </a-menu-item>
                        <a-menu-item>
                          <a-button type="link"  size="small" class="btn-item" @click="handleEdit(record)" :disabled="isEditDisabled(record)">编辑 </a-button>
                        </a-menu-item>
                        <a-menu-item
                          v-if="
                                            (
                                                (record.status === '未开始' ||
                                                    record.status === '待分发') &&
                                                record.myCreated
                                            )
                                        "
                        >
                          <a-button type="link"  size="small" class="btn-item" @click="toDelete(record)">删除 </a-button>
                        </a-menu-item>
                        <a-menu-item v-permission="'3000001145_vid_zkfzrjxdj7'">
                          <a-popconfirm title="请确认是否提醒该工单相关人员？" @confirm="toRmind(record.id)" :disabled="!record.pmoOrNot">
                            <a-button type="link"  size="small" class="btn-item" :disabled="!record.pmoOrNot">催办 </a-button>
                          </a-popconfirm>
                        </a-menu-item>
                        <a-menu-item>
                          <a-button type="link"  size="small" class="btn-item" @click="handleDetail(record.id)" >详情 </a-button>
                        </a-menu-item>
                      </a-menu>
                    </template>
                  </a-dropdown>

                </a-space>
              </template>
            </template>
          </a-table>
          </div>
        </a-spin>
      </div>

      <div class="pagination-div">
        <a-pagination
          v-model:current="pagination.current"
          :total="pagination.total"
          :show-total="pagination.showTotal"
          :page-size="pagination.pageSize"
          show-quick-jumper
          @show-size-change="pageSizeChange"
          @change="pageChange"
        />
      </div>

      <!-- end vid_met8bhslls 自定义模板_5x2uqbdvih -->
    </a-spin>
  </div>
</template>
<script setup lang="tsx">
import {
  h, ref, reactive, toRaw, markRaw, watch, computed,
  onBeforeMount, onMounted, onBeforeUnmount, onUnmounted, onActivated, onDeactivated
} from "vue";
import { useRoute, useRouter } from 'vue-router';
const router = useRouter();
const route = useRoute();
import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios';
import { cloneDeep, localGet, merge, getDifferenceArray, traversalTreeStructure, checkCaseCondition, renderStringInTemplate, handleBreadcrumbJump, throttle, permission, getComponentParamsValue } from '@/utils/index';
import { isNullOrEmpty, isEmptyArr, isNullOrUnDef, isContained, isArray, isEmpty, isObject } from '@/utils/is';
import dayjs from 'dayjs';
import { getPagePcChartsDataSourceConvert } from '@/utils/chart';
import { message, notification, Modal } from 'ant-design-vue'
import { propertyFormatByNumber, propertyFormatByPercentage, propertyFormatByDate, parseSubFromDataList } from '@/utils/format';
import colorTheme from '@/design/custom-theme.json';
/*** PUBLISH_EXEGESIS ***
 import UserTableRecords from '@/model/UserTableRecords';
 import { getAppBaseUrl } from '@/utils/index';
 import { sendToken } from "@/hooks/useIframeToken";
 import { useSystemStore } from "@/store/modules/system";
 const systemStore = useSystemStore();
 *** PUBLISH_EXEGESIS ***/



  // 获取传入的流程ID和组件参数
const props = defineProps({
    'processInstanceId': {
      type: [String,Number,Boolean],
      default: undefined,
    },
  })
const immediateWatch = (source, callback) => {
  watch(source, callback, {deep: true,immediate: true })
}



/* -------------------------- 属性定义 -------------------------- */

const setTimeOutList = [];
const pageLoading = reactive({
  loading: false,
  tip: undefined
});
const authInfo = localGet('app-user-store');




// 处理校验
const setSubFormName =(parentInfo, name)=>{
  return [parentInfo.parents, parentInfo.cycleIndex, name];
}


/* ========================== 属性定义 ========================== */


/* -------------------------- 元素数据引用 -------------------------- */


/* ========================== 元素数据引用 ========================== */


/* -------------------------- 页面数据 -------------------------- */


/* ========================== 页面数据 ========================== */



/* -------------------------- 响应 -------------------------- */

/* ========================== 响应 ========================== */


/* -------------------------- 函数 -------------------------- */

/* ========================== 函数 ========================== */


/* -------------------------- 页面参数 -------------------------- */

const pageParameter_state = reactive({
  'processInstanceId': props.processInstanceId ?? route.query.processInstanceId,
})

/* ========================== 页面参数 ========================== */


/* -------------------------- 组件事件处理方法 -------------------------- */

// ---------------------------- 组件数据同步 ----------------------------

// ============================ 组件数据同步 ============================


/* ========================== 组件事件处理方法 ========================== */


/* -------------------------- 生命周期 -------------------------- */
// 用于参数变更后重新执行自定义指令
const queryUpdateFlag = ref(0);
onMounted(() => { ;

});

onUnmounted(() => {
  // 销毁定时器
  setTimeOutList.forEach(({ repeat, timer }) => {
    repeat ?  clearInterval(timer): clearTimeout(timer);
  });
});

/* ========================== 生命周期 ========================== */


/* -------------------------- 数据关联处理 -------------------------- */





/* -------------------------- 表单数据同步 -------------------------- */
/* ========================== 表单数据同步 ========================== */

/* ========================== 数据关联处理 ========================== */


/* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */

/* ========================== 不同组件自定义的处理逻辑 ========================== */


// ================================定制化逻辑========================================
//     富文本设置
import { nextTick } from 'vue'
onMounted(() => {
  getViewSetting()
  window.addEventListener('resize', calcTableHeight)
  getTreeData()
  const urlParams = new URLSearchParams(window.location.search)
  // 获取单个参数
  state.filter.keyWords = urlParams.get('name')
  state.filter.number = urlParams.get('number')
  if (urlParams.get('factoryCode')) {
    state.filter.factoryCode = urlParams.get('factoryCode')
    state.filter.factoryType = 'FACTORY'
  } else {
    console.log('没有code')
  }
  getAllUser()
  getPmName()
  getPmo()
  getData()
  getAreaList()
  getCustomerList()
  getProjectList()
  getWorkType()
  getWarnList()
  getWtly()
  getClassfy()
  calcTableHeight()
})
onBeforeUnmount(() => {
  window.removeEventListener('resize', calcTableHeight)
})
const headerOffset = ref(265)
const calcTableHeight = () => {
  state.tableHeight = window.innerHeight - 180 - headerOffset.value
}
const dataLoading = ref(false)
import { QuillEditor, Quill } from '@vueup/vue-quill'
import ImageUploader from 'quill-image-uploader'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
const titleConfig = [
  { Choice: ' .ql-bold', title: '加粗' },
  { Choice: ' .ql-italic', title: '斜体' },
  { Choice: ' .ql-underline', title: '下划线' },
  { Choice: ' .ql-strike', title: '删除线' },
  { Choice: ' .ql-blockquote', title: '块引用' },
  { Choice: ' .ql-code-block', title: '插入代码' },
  { Choice: ' .ql-size', title: '字体大小' },
  { Choice: ' .ql-size', title: '字体大小' },
  { Choice: ' .ql-color', title: '字体颜色' },
  { Choice: ' .ql-background', title: '字体背景颜色' },
  { Choice: ' .ql-list[value="ordered"]', title: '有序列表' },
  { Choice: ' .ql-list[value="bullet"]', title: '无序列表' },
  { Choice: ' .ql-header[value="1"]', title: '1级标题' },
  { Choice: ' .ql-header[value="2"]', title: '2级标题' },
  { Choice: ' .ql-align', title: '对齐方式' },
  { Choice: ' .ql-clean', title: '清除字体格式' },
  { Choice: ' .ql-image', title: '图像' },
  { Choice: ' .ql-size .ql-picker-item[data-value="small"]', title: '小号' },
  { Choice: ' .ql-size .ql-picker-item[data-value="large"]', title: '大号' },
  { Choice: ' .ql-size .ql-picker-item[data-value="huge"]', title: '超大号' },
  { Choice: ' .ql-size .ql-picker-item:nth-child(2)', title: '标准' },
  { Choice: ' .ql-align .ql-picker-item:first-child', title: '居左对齐' },
  { Choice: ' .ql-align .ql-picker-item[data-value="center"]', title: '居中对齐' },
  { Choice: ' .ql-align .ql-picker-item[data-value="right"]', title: '居右对齐' },
  { Choice: ' .ql-align .ql-picker-item[data-value="justify"]', title: '两端对齐' }
]
// 注册图片上传模块
Quill.register('modules/imageUploader', ImageUploader)

// 将本地文件转换为URL
const getLocalImageURL = file => {
  return new Promise(resolve => {
    const reader = new FileReader()
    reader.onload = e => {
      resolve(e.target.result)
    }
    reader.readAsDataURL(file)
  })
}

// 表单数据

// Quill 编辑器选项
const editorOption = ref({
  modules: {
    toolbar: [
      ['bold', 'italic', 'underline', 'strike'], // 加粗，斜体，下划线，删除线
      ['blockquote', 'code-block'], // 引用，代码块
      [{ header: 1 }, { header: 2 }], // 标题1，标题2
      [{ list: 'ordered' }, { list: 'bullet' }], // 有序列表，无序列表
      [{ size: ['small', false, 'large', 'huge'] }], // 文字大小
      [{ color: [] }, { background: [] }], // 字体颜色，背景颜色
      [{ align: [] }], // 对齐
      ['clean'], // 清除格式
      ['image'] // 链接，图片，视频
    ]
    // ImageUploader: imageHandler
  }
})

// 将 dataURL 转换为 File 对象的辅助函数
const dataURLtoFile = (dataurl, filename) => {
  const arr = dataurl.split(',')
  const mime = arr[0].match(/:(.*?);/)[1]
  const bstr = atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], filename, { type: mime })
}

function initTitle() {
  document.getElementsByClassName('ql-editor')[0].dataset.placeholder = ''
  for (let item of titleConfig) {
    let tip = document.querySelector('.ql-toolbar' + item.Choice)
    if (!tip) continue
    tip.setAttribute('title', item.title)
  }
}
//     富文本设置
const pageSizeChange = (current, size) => {
  pagination.value.current = current
  pagination.value.pageSize = size
  getData()
}
const pageChange = (page, pageSize) => {
  console.log(page);
  pagination.value.current = page
  pagination.value.pageSize = pageSize
  getData(false,page)
}
const pagination = ref({
  current: 1,
  pageSize: 100,
  showSizeChanger: true,
  total: 0,
  pageSizeOptions: ['20', '40', '60', '80', '100'],
  showTotal: total =>
    `共 ${total} 个项目 第 ${pagination.value.current}/${Math.ceil(total / pagination.value.pageSize)}页`
})
// const activeKey = ref('全部工单')
const state = reactive({
  filter: {
    type: undefined,
    monitorScene: undefined,
    priority: undefined,
    questionSource: undefined,
    status: '',
    timeout: undefined,
    keyWords: undefined,
    number: undefined,
    factoryCode: undefined,
    production: undefined,
    pmName: undefined,
    pmoName: undefined,
    environment: undefined,
    createdByName: undefined,
    solverName: undefined,
    factoryType: undefined,
    rootCauseClassify: undefined,
    createdTimeList: [],
    projectIdList: []
  },
  activeKey: "''",
  tableHeight: 400,
  treeData: [],
  tagList: [],
  statusList: [
    {
      label: '未开始',
      value: '未开始'
    },
    {
      label: '解决中',
      value: '解决中'
    },
    {
      label: '已解决',
      value: '已解决'
    },
    {
      label: '已关闭',
      value: '已关闭'
    },
    {
      label: '已回访',
      value: '已回访'
    }
  ],
  changeStausList: [
    {
      label: '正在处理',
      value: '正在处理'
    },
    {
      label: '已解决',
      value: '已解决'
    },
    {
      label: '无需解决',
      value: '无需解决'
    },
    {
      label: '申请流转',
      value: '申请流转'
    }
  ],
  changeHaveSonStausList: [],
  sortList: [
    {
      label: '工单类型正序',
      value: 'type-asc'
    },
    {
      label: '工单类型倒序',
      value: 'type-desc'
    },
    {
      label: '优先级正序',
      value: 'priority-asc'
    },
    {
      label: '优先级倒序',
      value: 'priority-desc'
    },
    {
      label: '工单状态正序',
      value: 'status-asc'
    },
    {
      label: '工单状态倒序',
      value: 'status-desc'
    },
    {
      label: '工单解决进度正序',
      value: 'progress-asc'
    },
    {
      label: '工单解决进度倒序',
      value: 'progress-desc'
    },
    {
      label: '所属区域正序',
      value: 'area_code-asc'
    },
    {
      label: '所属区域倒序',
      value: 'area_code-desc'
    },
    {
      label: '所属项目阶段正序',
      value: 'milepost_id-asc'
    },
    {
      label: '所属项目阶段倒序',
      value: 'milepost_id-desc'
    },
    {
      label: '所属客户正序',
      value: 'customer-asc'
    },
    {
      label: '所属客户倒序',
      value: 'customer-desc'
    },
    {
      label: '所属产品正序',
      value: 'production-asc'
    },
    {
      label: '所属产品倒序',
      value: 'production-desc'
    },
    {
      label: '所属环境正序',
      value: 'environment-asc'
    },
    {
      label: '所属环境倒序',
      value: 'environment-desc'
    },
    {
      label: '创建人正序',
      value: 'created_by-asc'
    },
    {
      label: '创建人倒序',
      value: 'created_by-desc'
    },
    {
      label: '创建时间正序',
      value: 'created_time-asc'
    },
    {
      label: '创建时间倒序',
      value: 'created_time-desc'
    },
    {
      label: '解决人正序',
      value: 'solver-asc'
    },
    {
      label: '解决人倒序',
      value: 'solver-desc'
    },
    {
      label: '计划完成时间正序',
      value: 'end_time-asc'
    },
    {
      label: '计划完成时间倒序',
      value: 'end_time-desc'
    },
    {
      label: '实际完成时间正序',
      value: 'finish_time-asc'
    },
    {
      label: '实际完成时间倒序',
      value: 'finish_time-desc'
    }
  ],
  dataList: [],
  sort: 'created_time-desc',
  collapseKey: [],
  addOrEditVisible: false,
  modalTitle: '',
  modalForm: {
    content: undefined,
    type: undefined,
    priority: undefined,
    questionSource: undefined,
    monitorScene: undefined,
    workHours: undefined,
    endTime: undefined,
    areaCode: undefined,
    projectId: undefined,
    milepostId: undefined,
    taskId: undefined,
    version: undefined,
    warningLevel: undefined,
    customer: undefined,
    production: undefined,
    environment: undefined,
    description: undefined,
    solverList: [],
    descriptionAttachmentList: [],
    qillData: ''
  },
  fatherLoading: false,
  sonLoading: false,
  editSonVisible: false,
  sonForm: {
    parentId: undefined,
    content: undefined,
    type: undefined,
    priority: undefined,
    questionSource: undefined,
    workHours: undefined,
    endTime: undefined,
    areaCode: undefined,
    projectId: undefined,

    version: undefined,
    customer: undefined,
    production: undefined,
    environment: undefined,
    description: undefined,
    solverList: [],
    descriptionAttachmentList: [],
    quillData: ''
  },
  deleteLoading: false,
  fileVisible: false,
  remarkVisible: false,
  remarks: '',
  changeHaveSonStatusVisible: false,
  changeStatusForm: {
    status: undefined,
    reason: '',
    attachmentList: [],
    workOrderId: undefined,
    solution: undefined
  },

  deleteVisible: false,
  areaList: [],
  projectList: [],
  milepostList: [],
  taskList: [],
  customList: [],
  environmentList: [],
  searchEnvironmentList: [],
  productList: [
    {
      label: '大模型平台',
      value: '大模型平台'
    },
    {
      label: '水泥配料',
      value: '水泥配料'
    },
    {
      label: '其他',
      value: '其他'
    }
  ],
  allUser: [],
  warnList: [],
  wtlyList: [],
  pmoList: [],
  pmNameList: [],
  previewImage: '',
  previewVisible: false,
  // 工单类型
  workTypeList: [],
  monitorSceneList: []
})
// 工单类型
// 获取告警级别list
function getWarnList() {
  get(' /solution-ppm-basic-data/api/v1/dictionary/search/GD.GJJB').then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    state.warnList = data.data.map(item => {
      return {
        label: item.itemName,
        value: item.itemCode
      }
    })
  })
}
// 问题来源
// 获取问题来源
function getWtly() {
  get(' /solution-ppm-basic-data/api/v1/dictionary/search/GD.WTLY').then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    state.wtlyList = data.data.map(item => {
      return {
        label: item.itemName,
        value: item.itemName
      }
    })
  })
}
// 获取工单类型字典值
function getWorkType() {
  get(' /solution-ppm-basic-data/api/v1/dictionary/search/GD.GDLX').then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    state.workTypeList = data.data.map(item => {
      return {
        label: item.itemName,
        value: item.itemName
      }
    })
  })
}
// 获取监控场景list
function getMonitorSceneList(flag) {
  const params = flag ? state.filter.type : state.modalForm.type
  get(` /solution-ppm-basic-data/api/v1/dictionary/search/${params}`).then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    state.monitorSceneList = data.data.map(item => {
      return {
        label: item.itemName,
        value: item.itemCode
      }
    })
  })
}
// 监控场景
function getPmo() {
  get('/solution-ppm-work-order/api/v1/work_order/role/search/PMO').then(data => {
    state.pmoList = data.data.map(item => {
      return {
        label: item,
        value: item
      }
    })
  })
}
function getPmName() {
  get('/solution-ppm-work-order/api/v1/work_order/role/search/PM').then(data => {
    state.pmNameList = data.data.map(item => {
      return {
        label: item,
        value: item
      }
    })
  })
}
// 获取环境
function getEnvironmentList() {
  if(!state.modalForm.customer){
    state.environmentList=[]
    return
  }
  let customerId = state.customList.find(item => item.name === state.modalForm.customer)?.id
  console.log(customerId)
  get(`/solution-ppm-work-order/api/v1/work_order/env?customerId=${customerId ? customerId : ''}`).then(data => {
    state.environmentList = data.data
  })
}
// 获取筛选环境
function getSearchEnvironmentList() {
  get(`/solution-ppm-work-order/api/v1/work_order/env_distinct`).then(data => {
    state.searchEnvironmentList = data.data
  })
}
// 获取产品
// 产品
function getProductList() {
  let envId = state.environmentList.find(item => item.name === state.modalForm.environment)?.id
  get(`/solution-ppm-work-order/api/v1/work_order/product?envId=${envId ? envId : ''}`).then(data => {
    state.productList = data.data
  })
}
// 获取版本
function getVersionList() {
  let envId = state.environmentList.find(item => item.name === state.modalForm.environment)?.id
  let productId = state.productList.find(item => item.name === state.modalForm.production)?.id
  get(
    `/solution-ppm-work-order/api/v1/work_order/version?envId=${envId ? envId : ''}&productId=${
      productId ? productId : ''
    }`
  ).then(data => {
    state.modalForm.version = data.data
  })
}
// 客户改变如果没有选区域自动带区域
function customerChange() {
  let arae = state.customList.find(item => item.name === state.modalForm.customer)
  if (arae) {
    state.modalForm.areaCode = arae.areaCode
  }
  state.modalForm.environment = undefined
}
// 区域变
function areaChange() {
  state.modalForm.customer =
    state.modalForm.projectId =
      state.modalForm.environment =
        state.modalForm.production =
          state.modalForm.version =
            state.modalForm.milepostId =
              state.modalForm.taskId =
                undefined
}
// 项目变
function projectChange() {
  state.modalForm.environment =
    state.modalForm.production =
      state.modalForm.version =
        state.modalForm.milepostId =
          state.modalForm.taskId =
            undefined
}
// 项目阶段变
function milepostChange() {
  state.modalForm.taskId = undefined
}
// 环境变
function environmentChange() {
  state.modalForm.production = state.modalForm.version = undefined
}
// 产品变
function productChange() {
  state.modalForm.version = undefined
  getVersionList()
}
//     跳父详情

function handleDetail(id) {
  const isLocal = window.location.host.includes('localhost')
  const targetPageId = '3000001112'
  const query = new URLSearchParams({ id }).toString()
  if (isLocal) {
    console.log('本地环境')
    const url = `${import.meta.env.VITE_PUBLIC_PATH}/page/${targetPageId}?${query}`
    window.open(url, '_blank')
  } else {
    // 提取 pathname，确保最后是 page/数字
    console.log('线上')
    const match = location.pathname.match(/^(.*\/page\/)\d+$/)
    if (match) {
      const basePath = match[1] // e.g., "/app_50000005/allin-app/app_3000000076/page/"
      const url = `${location.origin}${basePath}${targetPageId}?${query}`
      window.open(url, '_blank')
    } else {
      console.error('当前 pathname 格式不符合预期，无法拼接新路径：', location.pathname)
    }
  }
}
// 跳子详情
function handleSonDetail(id) {
  window.open(`${import.meta.env.VITE_PUBLIC_PATH}/page/3000000787?id=${id}&url=3000000784`, '_blank')
  // router.push(`${import.meta.env.VITE_PUBLIC_PATH}/page/3000000787?id=${id}&url=3000000784`)
}
//     跳审批
function handelApprove() {
  router.push(`${import.meta.env.VITE_PUBLIC_PATH}/page/3000000788`)
}
const currentData = ref({})
//     新建工单
function handleAdd() {
  state.monitorSceneList = []
  resetCurrentData()
  state.addOrEditVisible = true
  state.modalTitle = '新建工单'

  nextTick(() => {
    initTitle()
    quillEditor.value.setContents('')
  })
}
function getTreeData() {
  get('/solution-ppm-work-order/api/v1/work_order/tree/search').then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    state.treeData = data.data
  })
}
// 获取类型
function handleTreeChange(value, label, extra) {
  if (value && extra) {
    const selectedNode = extra.triggerNode.props // 获取选中的节点
    if (selectedNode) {
      const type = selectedNode.nodeType // 获取type字段
      // 将type字段传递给后端
      if (type) {
        state.filter.factoryType = type
      }
    }
  } else {
    state.filter.factoryType = undefined
  }
}
//     编辑工单
async function handleEdit(record) {
  console.log(record);
  await resetCurrentData()
  currentData.value = record
  await Object.assign(state.modalForm, record)

  // 按顺序调用函数
  await getMonitorSceneList()
  await getCustomerList() // 获取客户列表
  await getProjectList() // 获取项目列表
  await getEnvironmentList() // 获取环境列表
  await getProductList() // 获取产品列表
  await getMilepostList()
  if (state.modalForm.milepostId) {
    await getTaskList()
  }

  // 显示模态框
  state.addOrEditVisible = true

  // 使用 nextTick 确保 DOM 更新后再执行
  nextTick(() => {
    get(`/solution-ppm-work-order/api/v1/work_order/details/${record.id}`).then(data => {
      let descriptionData = JSON.parse(data.data.workOrderDto.description)
      quillEditor.value.setContents(descriptionData)
    })
  })

  state.modalTitle = '编辑工单'
}

// 区域
function getAreaList() {
  get('/solution-ppm-work-order/api/v1/work_order/area_info').then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    state.areaList = data.data.map(item => {
      return {
        label: item.areaName,
        value: item.areaCode
      }
    })
  })
}
// 项目
function getProjectList() {
  if (state.modalForm.areaCode) {
    get(`/solution-ppm-work-order/api/v1/work_order/project_by_area_code/${state.modalForm.areaCode}`).then(
      data => {
        if (data.code !== 200) {
          message.error(data.message)
          return
        }
        state.projectList = data.data
      }
    )
  } else {
    get(`/solution-ppm-work-order/api/v1/work_order/project_by_area_code/0`).then(data => {
      if (data.code !== 200) {
        message.error(data.message)
        return
      }
      state.projectList = data.data
    })
  }
}
// 项目阶段
function getMilepostList() {
  if (!state.modalForm.projectId) {
    state.milepostList = []
    return
  }
  get(`/solution-ppm-work-order/api/v1/work_order/milepost_by_project_id/${state.modalForm.projectId}`).then(
    data => {
      if (data.code !== 200) {
        message.error(data.message)
        return
      }
      state.milepostList = data.data
    }
  )
}

// 任务
function getTaskList() {
  if (!state.modalForm.milepostId) {
    state.taskList = []
    return
  }
  get(
    `/solution-ppm-work-order/api/v1/work_order/get_by_milepost_id/${state.modalForm.milepostId}`
  ).then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    state.taskList = data.data
  })
}
// 客户
function getCustomerList() {
  get(
    `/solution-ppm-work-order/api/v1/work_order/customer?areaCode=${
      state.modalForm.areaCode ? state.modalForm.areaCode : ''
    }`
  ).then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    state.customList = data.data
  })
}

//     父工单提交表单
function submit() {
  formRef.value.validate().then(async () => {
    state.fatherLoading = true
    const deltaContent = quillEditor.value.getContents()

    const imageUploadPromises = []

    deltaContent.ops.forEach(op => {
      if (op.insert && op.insert.image && op.insert.image.startsWith('data:')) {
        const localSrc = op.insert.image

        // 如果是 base64 图片，上传并替换为 URL
        const file = dataURLtoFile(localSrc, 'image.png') // 将 base64 转换为 File 对象

        const uploadPromise = uploadFileAPI(file).then(({ data: { fullUrl } }) => {
          // 替换 op 中的 base64 URL 为服务器返回的 URL
          op.insert.image = fullUrl
        })

        imageUploadPromises.push(uploadPromise)
      }
    })
    try {
      await Promise.all(imageUploadPromises)
      if (currentData.value.id) {
        // 编辑保存逻辑
        const params = { ...state.modalForm }
        params.description = JSON.stringify(deltaContent)
        put('/solution-ppm-work-order/api/v1/work_order', params)
          .then(data => {
            if (data.code !== 200) {
              message.error(data.message)
              return
            }
            message.success(data.message)
            state.addOrEditVisible = false
            resetFather()
            getData()
          })
          .finally(() => {
            state.fatherLoading = false
          })
      } else {
        // 新建保存逻辑
        const params = { ...state.modalForm }
        params.description = JSON.stringify(deltaContent)
        post('/solution-ppm-work-order/api/v1/work_order', params)
          .then(data => {
            if (data.code !== 200) {
              message.error(data.message)
              return
            }
            message.success(data.message)
            state.addOrEditVisible = false
            resetFather()
            getData()
          })
          .finally(() => {
            state.fatherLoading = false
          })
      }
    } catch (error) {
      state.fatherLoading = false
      console.error('图片上传失败', error)
      return // 终止提交
    }
  })
}
function fatherCancel() {
  state.addOrEditVisible = false
  resetFather()
}
function resetFather() {
  state.modalForm = {
    content: undefined,
    type: undefined,
    priority: undefined,
    questionSource: undefined,
    workHours: undefined,
    endTime: undefined,
    areaCode: undefined,
    projectId: undefined,
    milepostId: undefined,
    taskId: undefined,
    version: undefined,
    warningLevel: undefined,
    customer: undefined,
    production: undefined,
    environment: undefined,
    description: undefined,
    monitorScene: undefined,
    solverList: [],
    qillData: ''
  }
}
function resetSon() {
  state.sonForm = {
    parentId: undefined,
    content: undefined,
    type: undefined,
    priority: undefined,
    questionSource: undefined,
    workHours: undefined,
    endTime: undefined,
    areaCode: undefined,
    projectId: undefined,
    version: undefined,
    customer: undefined,
    production: undefined,
    environment: undefined,
    description: undefined,
    solverList: [],
    quillData: ''
  }
}
const formRef = ref(null)
// 上传API
const uploadFileAPI = async file => {
  const data = new FormData()
  data.append('file', file)

  return post('/file-storage/api/v1/file/upload', data)
    .then(({ data: { fullUrl } }) => {
      return { data: { fullUrl } }
    })
    .catch(error => {
      console.error('上传图片出错:', error)
      throw error // 抛出错误以供外部处理
    })
}

//     子工单编辑
function editSon(record) {
  resetCurrentData()
  currentData.value = record
  sonState.modalTitle = '编辑子工单'
  state.editSonVisible = true
  Object.assign(state.sonForm, record)
  nextTick(() => {
    get(`/solution-ppm-work-order/api/v1/work_order/details/${record.id}`).then(data => {
      let descriptionData = JSON.parse(data.data.workOrderDto.description)
      sonQuillRef.value.setContents(descriptionData)
    })
  })
}
const sonRef = ref(null)

function cancelSon() {
  resetSon()
  state.editSonVisible = false
}
async function submitSon() {
  state.sonLoading = true
  sonRef.value.validate().then(async () => {
    const deltaContent = sonQuillRef.value.getContents()
    const imageUploadPromises = []

    deltaContent.ops.forEach(op => {
      if (op.insert && op.insert.image && op.insert.image.startsWith('data:')) {
        const localSrc = op.insert.image

        // 如果是 base64 图片，上传并替换为 URL
        const file = dataURLtoFile(localSrc, 'image.png') // 将 base64 转换为 File 对象

        const uploadPromise = uploadFileAPI(file).then(({ data: { fullUrl } }) => {
          // 替换 op 中的 base64 URL 为服务器返回的 URL
          op.insert.image = fullUrl
        })

        imageUploadPromises.push(uploadPromise)
      }
    })

    try {
      await Promise.all(imageUploadPromises)

      if (currentData.value.id) {
        // 编辑保存逻辑
        const params = { ...state.sonForm }
        params.description = JSON.stringify(deltaContent)
        put('/solution-ppm-work-order/api/v1/work_order', params)
          .then(data => {
            if (data.code !== 200) {
              message.error(data.message)
              return
            }
            message.success(data.message)
            state.editSonVisible = false
            resetSon()
            getData()
          })
          .finally(() => {
            state.sonLoading = false
          })
      } else {
        // 新建保存逻辑
        const params = { ...state.sonForm }
        params.description = JSON.stringify(deltaContent)
        post('/solution-ppm-work-order/api/v1/work_order', params)
          .then(data => {
            if (data.code !== 200) {
              message.error(data.message)
              return
            }
            message.success(data.message)
            state.editSonVisible = false
            resetSon()
            getData()
          })
          .finally(() => {
            state.sonLoading = false
          })
      }
    } catch (error) {
      state.sonLoading = false
      console.error('图片上传失败', error)
      return // 终止提交
    }
  })
}
// 父上传文件
function handlerFatherUpload(file) {
  state.fatherLoading = true
  const data = new FormData()
  data.append('file', file)
  post('/file-storage/api/v1/file/upload', data)
    .then(({ data: { fullUrl } }) => {
      if (data) {
        // 新文件对象
        const newFile = {
          uid: file.uid,
          lastModified: file.lastModified,
          name: file.name,
          size: file.size,
          type: file.type,
          status: 'done',
          url: fullUrl
        }

        // 去重，保留一个副本
        state.modalForm.descriptionAttachmentList = [
          // 保留已存在文件（去除重复）
          ...state.modalForm.descriptionAttachmentList.filter(
            item => item.uid !== file.uid && item.name !== file.name
          ),
          // 添加新的文件
          newFile
        ]
      }
      state.fatherLoading = false
    })
    .catch(e => {
      message.error('上传失败' + e)
    })

  return false
}
// 父移除文件
function handlerFatherRemove(file) {
  state.modalForm.descriptionAttachmentList = state.modalForm.descriptionAttachmentList.filter(
    item => item.uid !== file.uid
  )
}
// 父上传文件

// 子上传附件
function handlerSonUpload(file) {
  state.sonLoading = true
  const data = new FormData()
  data.append('file', file)

  post('/file-storage/api/v1/file/upload', data)
    .then(({ data: { fullUrl } }) => {
      if (data) {
        // 新文件对象
        const newFile = {
          uid: file.uid,
          lastModified: file.lastModified,
          name: file.name,
          size: file.size,
          type: file.type,
          status: 'done',
          url: fullUrl
        }

        // 去重，保留一个副本
        state.sonForm.descriptionAttachmentList = [
          // 保留已存在文件（去除重复）
          ...state.sonForm.descriptionAttachmentList.filter(
            item => item.uid !== file.uid && item.name !== file.name
          ),
          // 添加新的文件
          newFile
        ]
      }
      state.sonLoading = false
    })
    .catch(e => {
      message.error('上传失败' + e)
      state.sonLoading = false
    })

  return false
}
function handlerSonRemove(file) {
  state.sonForm.descriptionAttachmentList = state.sonForm.descriptionAttachmentList.filter(
    item => item.uid !== file.uid
  )
}
// 子上传附件

function resetCurrentData() {
  currentData.value = {}
}
const quillEditor = ref(null) // 引用QuillEditor组件
const sonQuillRef = ref(null) // 引用QuillEditor组件
const taskPeopleList = ref([])
function handlerAddPeople(name) {
  if (state.modalForm.solverList.indexOf(name) !== -1) {
    state.modalForm.solverList = state.modalForm.solverList.filter(item => item !== name)
  } else {
    state.modalForm.solverList[0] = name
  }
}

function getAllUser() {
  get('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/allUser').then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    state.allUser = data.data.userDtoList
  })
}
function findItemNameByCode(tree, code) {
  for (const node of tree) {
    if (node.itemCode === code) return node.itemName
    if (node.children) {
      const result = findItemNameByCode(node.children, code)
      if (result) return result
    }
  }
  return null
}
const selectedItemName = computed(() => {
  return findItemNameByCode(state.tagList, state.filter.rootCauseClassify)
})
// 获取列表
function getData(flag,page) {
  if (flag) {
    pagination.value.current = 1
  }
  dataLoading.value = true
  post('/solution-ppm-work-order/api/v1/work_order/search', {
    ...state.filter,
    pageSize: pagination.value.pageSize,
    pageNo: pagination.value.current,
    directionField: state.sort,
    rootCauseClassify: selectedItemName.value,
    myFollow:activeKey.value==='我的关注'?true:false,
    status:activeKey.value==='我的关注'?'':activeKey.value,
  })
    .then(data => {
      if (data.code !== 200) {
        message.error(data.message)
        return
      }
      if(page>data.data.totalPage){
        getData(totalPage)
        return;
      }
      state.dataList = data.data.content
      pagination.value.total = data.data.totalElements
      if (data.data.content.length > 0) {
        state.collapseKey=[(String(state.dataList[0].id))]
        newState.isExpandAll = false
      }
    })
    .finally(() => {
      dataLoading.value = false
    })
}
function resetData() {
  state.filter = {
    type: undefined,
    priority: undefined,
    monitorScene: undefined,
    questionSource: undefined,
    timeout: undefined,
    keyWords: undefined,
    number: undefined,
    factoryCode: undefined,
    production: undefined,
    pmName: undefined,
    pmoName: undefined,
    environment: undefined,
    createdByName: undefined,
    solverName: undefined,
    factoryType: undefined,
    rootCauseClassify: undefined,
    createdTimeList: []
  }
  pagination.value.current = 1
  pagination.value.pageSize = 100
  getData()
}

//     计算解决时间
function getSolveTime() {
  // 获取当前时间
  let currentDate = dayjs()
  let num = state.modalForm.workHours
  // 计算新时间
  let newDate = currentDate.add(num, 'hour')

  // 格式化新时间为 "YYYY-MM-DD HH:mm" 格式
  let formattedDate = newDate.format('YYYY-MM-DD HH:mm:ss')

  state.modalForm.endTime = formattedDate
}
//     根据类型获取解决时间
function getSolveTimeByType(type) {
  let num = 0
  if (type == 'p0') {
    num = 4
    state.modalForm.workHours = 4
  } else if (type == 'p1') {
    num = 24
    state.modalForm.workHours = 24
  } else if (type == 'p2') {
    num = 96
    state.modalForm.workHours = 96
  } else if (type == 'p3') {
    num = 48
    state.modalForm.workHours = 336
  }
  getSolveTime()
}
function hanldeTypeChange() {
  if (state.modalForm.type === '产品需求') {
    state.modalForm.priority = 'p3'
    getSolveTimeByType('p3')
  } else {
    state.modalForm.priority = state.modalForm.endTime = state.modalForm.workHours = undefined
  }
}
function handleSearchTypeChange() {
  state.filter.monitorScene = undefined
}

function handlerDownload(item) {
  pageLoading.loading = true
  pageLoading.tip = '文件下载中...'
  fetch(item.url)
    .then(response => response.blob())
    .then(blob => {
      const downloadLink = document.createElement('a')
      const url = URL.createObjectURL(blob)
      downloadLink.href = url
      downloadLink.setAttribute('download', item.name)
      downloadLink.style.display = 'none'
      document.body.appendChild(downloadLink)
      downloadLink.click()
      document.body.removeChild(downloadLink)

      // Release the object URL after the download
      URL.revokeObjectURL(url)
      pageLoading.loading = false
    })
    .catch(err => {
      console.error('Download failed', err)
    })
}

function handleDelete() {
  deleteRef.value.validate().then(() => {
    state.deleteLoading = true
    del(`/solution-ppm-work-order/api/v1/work_order/${currentData.value.id}`)
      .then(data => {
        if (data.code !== 200) {
          message.error(data.message)
          return
        }
        message.success(data.message)
        state.deleteVisible = false
        getData()
      })
      .finally(() => {
        state.deleteLoading = false
      })
  })
}
function toDelete(record) {
  resetCurrentData()
  currentData.value = record
  state.deleteVisible = true
}
//     预览图片
function previewAttachment(item) {
  // 检查附件类型
  if (item.type.startsWith('image')) {
    state.previewImage = item.url // 设置预览图片的URL
    state.previewVisible = true // 显示模态框
  } else {
    // state.isImagePreview = false;
    // // 如果是其他类型的文件，直接在模态框中显示
    // state.previewFileUrl = item.url; // 设置预览文件的URL
    message.info('目前仅支持图片预览')
  }
}
//    新需求
const newState = reactive({
  changeStatusLoading: false,
  isExpandAll: false,
  circulationVisible: false,
  resolvingVisible: false,
  resolvedVisible: false,
  circulationForm: {
    solverList: [],
    status: '流转'
  },
  resolvingForm: {
    solution: '',
    status: '解决中'
  },
  resolvedForm: {
    solution: '',
    attachmentList: [],
    status: '已解决',
    solutionDetail: ''
  },
  closeForm: {
    status: '关闭'
  },
  workOrderId: undefined
})
const circulationFormRef = ref(null)
const resolvingFormRef = ref(null)
const resolvedFormRef = ref(null)
const newRules = {
  solutionDetail: [
    {
      validator: (_, value) => {
        // 如果是 HTML 字符串则先处理为文本
        if (typeof value === 'string') {
          const text = value.replace(/<[^>]+>/g, '').trim()
          return text ? Promise.resolve() : Promise.reject(new Error('请输入解决方案详述'))
        }

        // 如果是 Delta（对象），提取纯文本
        if (typeof value === 'object' && value?.ops) {
          const plainText = value.ops
            .map(op => {
              return typeof op.insert === 'string' ? op.insert : ''
            })
            .join('')
            .trim()

          return plainText ? Promise.resolve() : Promise.reject(new Error('请输入解决方案详述'))
        }

        return Promise.reject(new Error('请输入解决方案详述'))
      },
      trigger: 'blur'
    }
  ]
}

const resolvingQuillRef = ref(null)
const resolvedQuillRef = ref(null)
//     全部展开
function handleExpandAll() {
  newState.isExpandAll = true
  let allId = []
  state.dataList.forEach(item => {
    allId.push(item.id)
  })
  state.collapseKey =allId
}
//     全部折叠
function handleCollapseAll() {
  newState.isExpandAll = false
  state.collapseKey = []
}
// 流转处理
function confirmCirculation() {
  circulationFormRef.value.validate().then(() => {
    newState.changeStatusLoading = true
    newState.circulationForm.workOrderId = newState.workOrderId
    newState.circulationForm.status = '未开始'
    put('/solution-ppm-work-order/api/v1/work_order/status_change', newState.circulationForm)
      .then(data => {
        if (data.code !== 200) {
          message.error(data.message)
          return
        }
        message.success(data.message)
        cancelCirculation()
        getData()
      })
      .finally(() => {
        newState.changeStatusLoading = false
        cancelCirculation()
      })
  })
}
function cancelCirculation() {
  newState.circulationVisible = false
  newState.circulationForm = {
    solverList: [],
    status: '流转'
  }
}

async function confirmResolving() {
  newState.changeStatusLoading = true
  try {
    const selectedSopList = newSopState.sopTableData.filter(item =>
      newSopState.selectedRowKeys.includes(item.sopStepId)
    )
    newState.resolvingForm.workOrderId = currentResolvingData.value.id
    const params = {
      attachmentList: newSopState.sopFileList,
      children: selectedSopList,
      parentId: currentResolvingData.value.addParentId,
      endTime: currentResolvingData.value.endTime,
      monitorScene: currentResolvingData.value.monitorScene
    }

    // 只有当 tag === 1 时，才先执行 createSopChildren
    if (currentResolvingData.value.tag === 1) {
      const createRes = await post('/solution-ppm-work-order/api/v1/work_order/createSopChildren', params)
      if (createRes.code !== 200) {
        message.error(createRes.message)
        return
      }
    }

    // 调用 status_change 接口
    const statusChangeRes = await put(
      '/solution-ppm-work-order/api/v1/work_order/status_change',
      newState.resolvingForm
    )
    if (statusChangeRes.code !== 200) {
      message.error(statusChangeRes.message)
      return
    }

    message.success(statusChangeRes.message)
    cancelResolving()
    resetNewState()
    getData()
  } catch (error) {
    message.error('操作失败，请重试')
    console.error('错误详情:', error)
  } finally {
    newState.changeStatusLoading = false
  }
}

function cancelResolving() {
  newState.resolvingVisible = false
}

const deltaData = ref(null)
const rootRef = ref(null)
async function confirmResolved() {
  newState.changeStatusLoading = true
  try {
    await resolvedFormRef.value.validate().catch(errors => {
      console.error('表单校验失败:', errors)
      message.error('请检查表单填写是否正确')
      throw new Error('表单校验未通过')
    })

    const deltaContent = resolvedQuillRef.value.getContents()
    deltaData.value = deltaContent // 保存一份 delta 数据

    const imageUploadPromises = []

    deltaContent.ops.forEach(op => {
      if (op.insert && op.insert.image && op.insert.image.startsWith('data:')) {
        const localSrc = op.insert.image
        const file = dataURLtoFile(localSrc, 'image.png')

        const uploadPromise = uploadFileAPI(file).then(({ data: { fullUrl } }) => {
          op.insert.image = fullUrl
        })

        imageUploadPromises.push(uploadPromise)
      }
    })

    await Promise.all(imageUploadPromises)

    // 如果 tag === 1，先调用 createSopChildren 接口
    if (resolvedData.value.tag === 1) {
      const params = {
        attachmentList: newSopState.sopFileList,
        children: newSopState.sopTableData.filter(item =>
          newSopState.selectedRowKeys.includes(item.sopStepId)
        ),
        parentId: resolvedData.value.addParentId,
        endTime: resolvedData.value.endTime,
        monitorScene: resolvedData.value.monitorScene
      }

      const createSopResponse = await post(
        '/solution-ppm-work-order/api/v1/work_order/createSopChildren',
        params
      )

      if (createSopResponse.code !== 200) {
        message.error(createSopResponse.message)
        return
      }
    }

    // 构造最终状态变更数据，注意不要修改 form 本身
    const payload = {
      ...newState.resolvedForm,
      workOrderId: resolvedData.value.id,
      status: '已解决',
      solutionDetail: JSON.stringify(deltaData.value) // 仅提交结构化数据
    }

    const statusChangeResponse = await put('/solution-ppm-work-order/api/v1/work_order/status_change', payload)

    if (statusChangeResponse.code !== 200) {
      message.error(statusChangeResponse.message)
      return
    }

    message.success(statusChangeResponse.message)
    cancelResolved()
    getData()
  } catch (error) {
    // 可选：日志
  } finally {
    newState.changeStatusLoading = false
  }
}
function saveRoot() {
  if (!resolvedData.value.parentId) {
    rootRef.value.validate().then(async () => {
      newState.changeStatusLoading = true

      const params = {
        responsibleParty: rootState.responsibleParty,
        businessType: rootState.businessType,
        rootCauseClassify: rootState.rootCauseClassify,
        rootCauseAnalysis: '',
        id: resolvedData.value.id
      }

      // === 单独处理 rootEditor 富文本图片上传 ===
      let rootDeltaContent = null
      try {
        rootDeltaContent = rootQuillEditor.value.getContents()
        const rootUploadTasks = rootDeltaContent.ops.map(async op => {
          if (op.insert?.image?.startsWith('data:')) {
            const file = dataURLtoFile(op.insert.image, 'image.png')
            const {
              data: { fullUrl }
            } = await uploadFileAPI(file)
            op.insert.image = fullUrl
          }
        })
        await Promise.all(rootUploadTasks)
        params.rootCauseAnalysis = JSON.stringify(rootDeltaContent)
      } catch (e) {
        console.error('处理 rootQuillEditor 出错：', e)
        // 同样不 return，继续提交
      }

      // === 提交接口 ===
      put('/solution-ppm-work-order/api/v1/work_order/root_cause_modify', params).then(data => {
        if (data.code !== 200) {
          message.error(data.message)
          newState.changeStatusLoading = false
          return
        }
        confirmResolved()
      })
    })
  } else {
    confirmResolved()
  }
}
function cancelResolved() {
  newState.resolvedVisible = false
}
function showCirculation(record) {
  newState.circulationVisible = true
  newState.workOrderId = record.id
}
const currentResolvingData = ref({})
// 开始解决
function showResolving(record, parentId) {
  if (record.tag === 1) {
    get(`/solution-ppm-work-order/api/v1/work_order/${record.id}/sop/steps`).then(data => {
      if (data.code !== 200) {
        message.error(data.message)
        return
      }
      // newSopState.sopTableData = groupSopData(data.data.filter(item => item.canCreated))
      newSopState.sopTableData = groupSopData(data.data)
    })
  } else {
    newSopState.sopTableData = []
  }
  newSopState.selectedRowKeys = []
  currentResolvingData.value = record
  if (parentId) {
    currentResolvingData.value.addParentId = parentId
  } else {
    currentResolvingData.value.addParentId = record.id
  }
  newState.workOrderId = record.id
  newState.resolvingVisible = true
}
const resolvedData = ref({})
function showResolved(record, parentId) {
  if (record.tag === 1) {
    get(`/solution-ppm-work-order/api/v1/work_order/${record.id}/sop/steps`).then(data => {
      if (data.code !== 200) {
        message.error(data.message)
        return
      }
      // newSopState.sopTableData = groupSopData(data.data.filter(item => item.canCreated))
      newSopState.sopTableData = groupSopData(data.data)
      // newSopState.solvedSOPList = groupSopData(data.data.filter(item => item.solveByMe))
      newSopState.solvedSOPList = groupSopData(data.data)
    })
  } else {
    newSopState.sopTableData = []
  }
  newSopState.selectedRowKeys = []
  resolvedData.value = record
  newState.resolvedVisible = true
  if (parentId) {
    resolvedData.value.addParentId = parentId
  } else {
    resolvedData.value.addParentId = record.id
  }
  newState.workOrderId = record.id
  get(`/solution-ppm-work-order/api/v1/work_order/details/${newState.workOrderId}`).then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    nextTick(async () => {
      let solutionDetail = JSON.parse(data.data.workOrderDto.solutionDetail)
      newState.resolvedForm.solution = data.data.workOrderDto.solution
      newState.resolvedForm.attachmentList = data.data.workOrderDto.attachmentList
      try {
        const solutionDetail = JSON.parse(data.data.workOrderDto.solutionDetail)
        const rootDetail = JSON.parse(data.data.workOrderDto.rootCauseAnalysis)

        // 即使第一个报错也不影响第二个执行
        try {
          resolvedQuillRef.value.setContents(solutionDetail)
        } catch (e) {
          console.warn('设置 solutionQuillEditor 报错:', e)
        }

        try {
          rootQuillEditor.value.setContents(rootDetail)
          rootDetailMsg.value = data.data.workOrderDto.rootCauseAnalysis
        } catch (e) {
          console.warn('设置 rootQuillEditor 报错:', e)
        }
      } catch (e) {
        console.warn('solutionDetail 解析失败', e)
      }
      rootState.rootCauseClassify = data.data.workOrderDto.rootCauseClassify || undefined
      rootState.responsibleParty = data.data.workOrderDto.responsibleParty || undefined
      rootState.businessType = data.data.workOrderDto.businessType || undefined
      await getResponsiblePartyList()
      await getBusinessTypeList()
      await getRootCauseClassifyList()
    })
  })
}
const rootDetailMsg = ref()
// 上传文件
function handlerResolvedUpload(file) {
  newState.changeStatusLoading = true
  const data = new FormData()
  data.append('file', file)

  post('/file-storage/api/v1/file/upload', data)
    .then(({ data: { fullUrl } }) => {
      if (data) {
        // 新文件对象
        const newFile = {
          uid: file.uid,
          lastModified: file.lastModified,
          name: file.name,
          size: file.size,
          type: file.type,
          status: 'done',
          url: fullUrl
        }

        // 去重，保留一个副本
        newState.resolvedForm.attachmentList = [
          // 保留已存在文件（去除重复）
          ...newState.resolvedForm.attachmentList.filter(
            item => item.uid !== file.uid && item.name !== file.name
          ),
          // 添加新的文件
          newFile
        ]
      }
      newState.changeStatusLoading = false
    })
    .catch(e => {
      message.error('上传失败' + e)
    })

  return false
}
// 移除文件
function handlerResolvedRemove(file) {
  newState.resolvedForm.attachmentList = newState.resolvedForm.attachmentList.filter(
    item => item.uid !== file.uid
  )
}
const styleMap = {
  '未开始': {
    background: '#F6F6F6 !important',
    borderLeft: '2px solid #A9A9A9'
  },
  '待分发': {
    background: '#FFEADC !important',
    borderLeft: '2px solid #FFC900'
  },
  '已解决': {
    background: '#EDF9E8 !important',
    borderLeft: '2px solid #52C41A'
  },
  '解决中': {
    background: '#EBF1FF  !important',
    borderLeft: '2px solid #3875FF'
  },
  '无需解决': {
    background: '#FFF8E0  !important',
    borderLeft: '2px solid #FFC900'
  },
  '已关闭': {
    background: '#EBEBEB !important',
    borderLeft: '2px solid #262626'
  },
  '已回访': {
    background: '#EFE6FB !important',
    borderLeft: '2px solid #9254DE'
  }
}

// 获取样式
function getTitleStyle(status,key) {
  const styles =  styleMap[status] || {}
  return key ? {[key]:styles[key]} : styles
}
const colorMap = {
  '未开始': { background: '#A9A9A9' },
  '已解决': { background: '#52C41A' },
  '解决中': { background: '#3875FF' },
  '无需解决': { background: '#FFC900' },
  '已关闭': { background: '#262626' },
  '已回访': { background: '#9254DE' },
  '待分发': { background: '#FF7D27' }
}
function getColorStyle(status) {
  return colorMap[status] || '#262626'
}
const classMap = {
  '未开始': 'status-wks',
  '已解决':'status-yjj',
  '解决中': 'status-jjz',
  '无需解决': 'status-wxjj',
  '已关闭': 'status-ygb',
  '已回访': 'status-yhf',
  '待分发': 'status-dff',
}
function getClassStatus(status) {
  return classMap[status] || 'status-default'
}
const borderMap = {
  '未开始': { borderLeft: '2px solid #A9A9A9' },
  '已解决': { borderLeft: '2px solid #52C41A' },
  '解决中': { borderLeft: '2px solid #3875FF' },
  '无需解决': { borderLeft: '2px solid #FFC900' },
  '已关闭': { borderLeft: '2px solid #262626' },
  '待分发': { borderLeft: '2px solid #FFC900' }
}
function getBorder(status) {
  return borderMap[status] || {}
}
// 判断按钮是否可用的计算属性
function isCirculationDisabled(item) {
  if (item.tag === 1) return true // 如果 tag 是 1，直接禁用按钮
  return !(
    (
      (item.status === '未开始' && item.solvers) || // 未开始且有solvers
      (item.status === '解决中' && item.solvers) || // 解决中且有solvers
      (item.status === '待分发' && item.distributed) ||
      item.tag === 1
    ) // 待分发且distributed为true
  )
}

// function isResolvingDisabled(item) {
//     return !(
//         (item.status === '未开始' && item.solvers) ||
//         (item.status === '已解决' && item.myCreated) ||
//         (item.status === '已关闭' && item.myCreated && item.tag !== 1) ||
//         (item.status === '已关闭' && item.pmoOrNot && item.tag !== 1)
//     )
// }
function isResolvingDisabled(item) {
  return !(item.status === '未开始' && item.solvers)
}
function isNoNeedSolveDisabled(item) {
  return !((item.status === '未开始' && item.solvers) || (item.status === '解决中' && item.solvers))
  // !(item.status === '未开始' && item.solvers) || !(item.status === '解决中' && item.solvers)
}
function isResolvedDisabled(item) {
  return (
    // !(item.status === '未开始' && item.solvers) && // 解决人解决中
    !(item.status === '解决中' && item.solvers)
  )
}
function isReOpenDisabled(item) {
  return !item.solvers || item.myCreated
}
function isCloseDisabled(item) {
  return (
    !(item.status === '已解决' && (item.myCreated || item.pmoOrNot)) &&
    !(item.status === '无需解决' && (item.myCreated || item.pmoOrNot))
  ) // 创建人或PMO关闭
}
function isEditDisabled(item) {
  if((item.myCreated||item.solvers)&&item.status==='已关闭'){
    return false
  }
  return ['无需解决', '已解决'].includes(item.status)
}
// function sonDisabled(item) {
//     return ['无需解决', '已关闭', '已解决','待分发'].includes(item.status) || item.tag === 1
// }
function sonDisabled(item) {
  return !(['未开始', '解决中'].includes(item.status) && item.tag !== 1 && item.myCreated)
}

function sopDisabled(item) {
  return item.tag !== 1 || ['无需解决', '已关闭', '已解决', '已回访'].includes(item.status)
}

function isReturnVisitDisabled(item) {
  return !(item.status === '已关闭' && (item.myCreated || item.pmoOrNot)) // 创建人或PMO回访
}
function handleReturnVisit(item) {
  const params = {
    workOrderId: item.id,
    status: '已回访'
  }
  newState.changeStatusLoading = true
  put('/solution-ppm-work-order/api/v1/work_order/status_change', params)
    .then(data => {
      if (data.code !== 200) {
        message.error(data.message)
        return
      }
      message.success(data.message)
      getData()
    })
    .finally(() => {
      newState.changeStatusLoading = false
    })
}
// 重新打开
function handlerReOpen(item) {
  const params = {
    workOrderId: item.id,
    status: '未开始'
  }
  if (item.actualStartTime) {
    params.status = '解决中'
  } else {
    params.status = '未开始'
  }
  put('/solution-ppm-work-order/api/v1/work_order/status_change', params).then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    message.success(data.message)
    getData()
  })
}
// 提醒
function toRmind(id) {
  get(`/solution-ppm-work-order/api/v1/work_order/remind/${id}`).then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    message.success('已经向工单关联人员发送提醒解决通知')
  })
}
function toggleCollapse(id) {
  const stringId = String(id) // 确保 id 为字符串格式
  if (isActive(stringId)) {
    // 如果当前面板是展开的，移除它的 ID
    state.collapseKey = state.collapseKey.filter(key => String(key) !== stringId)
  } else {
    // 否则，将它的 ID 添加到 collapseKey 中
    state.collapseKey.push(stringId)
  }
}

function isActive(id) {
  const stringId = String(id) // 确保 id 为字符串格式
  return state.collapseKey.includes(stringId) // 检查该 ID 是否在 collapseKey 中
}

// 多选框改成单选
function changeStatusSolverChange(value) {
  // if (Array.isArray(value) && value.length > 1) {
  //     newState.circulationForm.solverList = [value[0]] // 只保留第一个选项
  // }
  if (Array.isArray(value)) {
    newState.circulationForm.solverList = [value[value.length - 1]] // 只保留最后一个选项
  } else {
    newState.circulationForm.solverList = [value] // 如果不是数组，说明只选中一个选项
  }
}
function fatherSolverChange(value) {
  // if (Array.isArray(value) && value.length > 1) {
  //     state.modalForm.solverList = [value[0]] // 只保留第一个选项
  // }
  if (Array.isArray(value)) {
    state.modalForm.solverList = [value[value.length - 1]] // 只保留最后一个选项
  } else {
    state.modalForm.solverList = [value] // 如果不是数组，说明只选中一个选项
  }
}
function sonSolverChange(value) {
  // if (Array.isArray(value) && value.length > 1) {
  //     state.sonForm.solverList = [value[0]] // 只保留第一个选项
  // }
  if (Array.isArray(value)) {
    state.sonForm.solverList = [value[value.length - 1]] // 只保留最后一个选项
  } else {
    state.sonForm.solverList = [value] // 如果不是数组，说明只选中一个选项
  }
}
//    新需求
//     新建子工单提出来
const sonState = reactive({
  modalTitle: '',
  noNeedVisible: false,
  noNeedLoading: false,
  noNeedRemark: undefined,
  deleteVisible: false,
  deleteRemark: undefined,
  deleteLoading: false
})
function handleAddSon(record) {
  resetCurrentData()
  // if (record.status !== '解决中' || record.status === '已关闭' || record.status === '已回访') {
  //     message.info('请将父工单状态变更为解决中后重试')
  //     return
  // }
  console.log(record)
  sonState.modalTitle = '新建子工单'
  state.sonForm.solverList = record.solverList
  state.editSonVisible = true
  state.sonForm.parentId = record.id
  sonQuillRef.value.setContents('')

  // nextTick(() => {
  //   initSonTitle()
  // })
}
const noNeedData = ref({})
function showNoNeed(item, parentId) {
  console.log(item)
  newSopState.selectedRowKeys = []
  noNeedData.value = item
  if (parentId) {
    noNeedData.value.addParentId = parentId
  } else {
    noNeedData.value.addParentId = item.id
  }
  if (item.tag === 1) {
    get(`/solution-ppm-work-order/api/v1/work_order/${item.id}/sop/steps`).then(data => {
      if (data.code !== 200) {
        message.error(data.message)
        return
      }
      // newSopState.sopTableData = groupSopData(data.data.filter(item => item.canCreated))
      newSopState.sopTableData = groupSopData(data.data)
    })
  } else {
    newSopState.sopTableData = []
  }
  get(`/solution-ppm-work-order/api/v1/work_order/details/${item.id}`).then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    sonState.noNeedRemark = item.remark
    sonState.noNeedVisible = true
    nextTick(async () => {
        const rootDetail = JSON.parse(data.data.workOrderDto.rootCauseAnalysis)
        try {
          rootQuillEditor.value.setContents(rootDetail)
          rootDetailMsg.value = data.data.workOrderDto.rootCauseAnalysis
        } catch (e) {
          console.warn('设置 rootQuillEditor 报错:', e)
        }
      rootState.rootCauseClassify = data.data.workOrderDto.rootCauseClassify || undefined
      rootState.responsibleParty = data.data.workOrderDto.responsibleParty || undefined
      rootState.businessType = data.data.workOrderDto.businessType || undefined

      await getResponsiblePartyList()
      await getBusinessTypeList()
      await getRootCauseClassifyList()
    })
  })

}
// function submitNoNeed() {
//     sonState.noNeedVisible = false
//     sonState.noNeedRemark = undefined
//     noNeedData.value = {}
// }
async function submitNoNeed() {
  sonState.noNeedLoading = true
  try {
    await noNeedRef.value.validate()
    const selectedSopList = newSopState.sopTableData.filter(item =>
      newSopState.selectedRowKeys.includes(item.sopStepId)
    )
    const params = {
      attachmentList: newSopState.sopFileList,
      children: selectedSopList,
      parentId: noNeedData.value.addParentId,
      endTime: noNeedData.value.endTime,
      monitorScene: noNeedData.value.monitorScene
    }

    // 只有当 tag === 1 时，才先执行 createSopChildren
    if (noNeedData.value.tag === 1) {
      const createRes = await post('/solution-ppm-work-order/api/v1/work_order/createSopChildren', params)
      if (createRes.code !== 200) {
        message.error(createRes.message)
        return
      }
    }

    // 调用 status_change 接口
    const statusChangeRes = await put('/solution-ppm-work-order/api/v1/work_order/status_change', {
      remark: sonState.noNeedRemark,
      status: '无需解决',
      workOrderId: noNeedData.value.id
    })
    if (statusChangeRes.code !== 200) {
      message.error(statusChangeRes.message)
      return
    }

    message.success(statusChangeRes.message)
    cancelNoNeed()
    resetNewState()
    cancelRootMsg()
    getData()
  } catch (error) {
    if (error?.errorFields) {
      // ✅ 这里确保只有校验失败时才会显示
      message.error('请检查表单填写是否正确')
    } else {
      message.error('操作失败，请重试')
      console.error('错误详情:', error)
    }
  } finally {
    sonState.noNeedLoading = false
  }
}
function cancelNoNeed() {
  sonState.noNeedVisible = false
  sonState.noNeedRemark = undefined
  noNeedData.value = {}
}
//     新需求工单sop
const newSopState = reactive({
  sopOkLoading: false,
  sopVisible: false,
  selectedRowKeys: [],
  sopTableData: [],
  //   sop父工单开始解决部分
  sopStartTableList: [],
  //   sop工单无需解决
  solvedSOPList: [],
  //   sop工单关闭
  sopCloseTableData: [],
  sopCloseVisible: false,
  //   sop已拒绝部分
  sopRemainingData: [],
  //   新建SOP子工单里的附件
  sopFileList: [],
  closeLoading: false,
  closeRemark: undefined
})
const sopColumns = [
  // {
  //     title: 'SOP名称',
  //     dataIndex: 'sopName',
  //     align: 'center',
  //     ellipsis: true,
  //     customCell: ({ rowSpan }) => {
  //         return {
  //             rowSpan: rowSpan
  //         }
  //     }
  // },
  {
    title: 'SOP步骤',
    dataIndex: 'sopStep',
    align: 'center',
    ellipsis: true
  },
  {
    title: '解决角色',
    dataIndex: 'solverRole',
    align: 'center',
    ellipsis: true
  }
]
function groupSopData(data) {
  let currentSopName = ''

  // 遍历数据，计算每一行的 rowSpan
  return data.map((item, index) => {
    if (currentSopName !== item.sopName) {
      // 更新当前的标识符
      currentSopName = item.sopName

      // 计算这个组的 rowSpan
      let rowSpan = 0
      for (let i = index; i < data.length; i++) {
        const currentItem = data[i]
        if (currentSopName === currentItem.sopName) {
          rowSpan += 1
        } else {
          break
        }
      }
      item.rowSpan = rowSpan
    } else {
      item.rowSpan = 0 // 如果是相同的组，重置 rowSpan
    }

    return item
  })
}
const currentAddSopRecord = ref({})
function handleAddSopSon(record) {
  get(`/solution-ppm-work-order/api/v1/work_order/${record.id}/sop/steps`).then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    // newSopState.sopTableData = groupSopData(data.data.filter(item => item.canCreated))
    newSopState.sopTableData = groupSopData(data.data)
    console.log(newSopState.sopTableData, 'asdas')
    currentAddSopRecord.value = record
    // TODO:获取sop列表
    newSopState.sopVisible = true
  })
}
// 新建sop子工单
function cancelSop() {
  newSopState.sopVisible = false
  currentAddSopRecord.value = {}
  resetNewState()
}
const sopSonLoading = ref(false)
function confirmSop() {
  const selectedSopList = newSopState.sopTableData.filter(item =>
    newSopState.selectedRowKeys.includes(item.sopStepId)
  )
  sopSonLoading.value = true
  const params = {
    attachmentList: newSopState.sopFileList,
    children: selectedSopList,
    parentId: currentAddSopRecord.value.id,
    endTime: currentAddSopRecord.value.endTime,
    monitorScene: currentAddSopRecord.value.monitorScene
  }
  post('/solution-ppm-work-order/api/v1/work_order/createSopChildren', params)
    .then(data => {
      if (data.code !== 200) {
        message.error(data.message)
        return
      }
      message.success(data.message)
      newSopState.sopVisible = false
      resetNewState()
      getData()
    })
    .finally(() => {
      sopSonLoading.value = false
    })

  currentAddSopRecord.value = {}
}
function resetNewState() {
  newSopState.sopTableData = []
  newSopState.selectedRowKeys = []
  newSopState.sopFileList = []
}
const onSopSelectChange = selectedRowKeys => {
  console.log(selectedRowKeys, 'selectedRowKeys')
  newSopState.selectedRowKeys = selectedRowKeys
}
const currentCloseData = ref({})
// 工单开始关闭
function handlerClose(item, parentId) {
  console.log(item)
  newSopState.selectedRowKeys = []
  currentCloseData.value = item
  if (parentId) {
    currentCloseData.value.addParentId = parentId
  } else {
    currentCloseData.value.addParentId = item.id
  }
  if (item.tag === 1) {
    get(`/solution-ppm-work-order/api/v1/work_order/${item.id}/sop/steps`).then(data => {
      if (data.code !== 200) {
        message.error(data.message)
        return
      }
      // newSopState.sopTableData = groupSopData(data.data.filter(item => item.canCreated))
      newSopState.sopTableData = groupSopData(data.data)
    })
  } else {
    newSopState.sopTableData = []
  }

  newSopState.sopCloseVisible = true
}
const deleteRef = ref(null)
const closeRef = ref(null)
const noNeedRef = ref(null)
// 工单确定关闭
async function confirmSopClose() {
  newSopState.closeLoading = true
  try {
    // ✅ 直接 await 表单校验，不需要 catch
    await closeRef.value.validate()

    const selectedSopList = newSopState.sopTableData.filter(item =>
      newSopState.selectedRowKeys.includes(item.sopStepId)
    )
    const params = {
      attachmentList: newSopState.sopFileList,
      children: selectedSopList,
      parentId: currentCloseData.value.addParentId,
      endTime: currentCloseData.value.endTime,
      monitorScene: currentCloseData.value.monitorScene
    }

    // 只有当 tag === 1 时，才先执行 createSopChildren
    if (currentCloseData.value.tag === 1) {
      const createRes = await post('/solution-ppm-work-order/api/v1/work_order/createSopChildren', params)
      if (createRes.code !== 200) {
        message.error(createRes.message)
        return
      }
    }

    // 调用 status_change 接口
    const statusChangeRes = await put('/solution-ppm-work-order/api/v1/work_order/status_change', {
      remark: newSopState.closeRemark,
      status: '已关闭',
      workOrderId: currentCloseData.value.id
    })
    if (statusChangeRes.code !== 200) {
      message.error(statusChangeRes.message)
      return
    }

    message.success(statusChangeRes.message)
    cancelClose()
    resetNewState()
    getData()
  } catch (error) {
    if (error?.errorFields) {
      // ✅ 这里确保只有校验失败时才会显示
      message.error('请检查表单填写是否正确')
    } else {
      message.error('操作失败，请重试')
      console.error('错误详情:', error)
    }
  } finally {
    newSopState.closeLoading = false
  }
}

function cancelClose() {
  newSopState.sopCloseVisible = false
  newSopState.closeRemark = undefined
  currentCloseData.value = {}
}
//     新建sop工单上传附件
// 父上传文件
function handlerSopUpload(file) {
  const data = new FormData()
  data.append('file', file)

  post('/file-storage/api/v1/file/upload', data)
    .then(({ data: { fullUrl } }) => {
      if (data) {
        // 新文件对象
        const newFile = {
          uid: file.uid,
          lastModified: file.lastModified,
          name: file.name,
          size: file.size,
          type: file.type,
          status: 'done',
          url: fullUrl
        }

        // 去重，保留一个副本
        newSopState.sopFileList = [
          // 保留已存在文件（去除重复）
          ...newSopState.sopFileList.filter(item => item.uid !== file.uid && item.name !== file.name),
          // 添加新的文件
          newFile
        ]
      }
      state.fatherLoading = false
    })
    .catch(e => {
      message.error('上传失败' + e)
    })

  return false
}
// 父移除文件
function handlerSopRemove(file) {
  newSopState.sopFileList = newSopState.sopFileList.filter(item => item.uid !== file.uid)
}
const downTemplateFileLoading = ref(false)
//     下载sop附件模板
function handleDownLoadSopTemplate(record) {
  downTemplateFileLoading.value = true
  post(`/solution-ppm-work-order/api/v1/work_order/download_template/${record.id}`, null, {
    responseType: 'blob'
  })
    .then(res => {
      console.log(res)
      if (res.type === 'application/octet-stream') {
        downloadZip(res, '附件模板.zip')
      } else {
        message.info('没有模板可以下载')
      }
      // if (res.code) {
      //     message.error(data.message)
      //     return
      // }
      // downloadZip(res, '附件模板.zip')
    })
    .finally(() => {
      downTemplateFileLoading.value = false
    })
}
function downloadZip(response, name) {
  const blob = new Blob([response], { type: 'application/zip;charset=utf-8' })
  const downloadElement = document.createElement('a')
  const href = window.URL.createObjectURL(blob)
  downloadElement.href = href
  downloadElement.download = name // 下载后文件名
  document.body.appendChild(downloadElement)
  downloadElement.click()
  document.body.removeChild(downloadElement)
  window.URL.revokeObjectURL(href)
  return href
}
function handlerDerivativeWorkOrder(item, flag) {
  put(`/solution-ppm-work-order/api/v1/work_order/switchDerivative/${item.id}`).then(data => {
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    message.success(data.message)
    getData()
  })
}
function getClassfy() {
  get(' /solution-ppm-basic-data/api/v1/dictionary/search_tree/GD.ZRF').then(data => {
    state.tagList = data.data
  })
}
const downloadExcel = (response, name) => {
  const blob = new Blob([response], {
    type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
  })
  const downloadElement = document.createElement('a')
  const href = window.URL.createObjectURL(blob) // 创建下载的链接
  downloadElement.href = href
  downloadElement.download = name // 下载后文件名
  document.body.appendChild(downloadElement)
  downloadElement.click() // 点击下载
  document.body.removeChild(downloadElement) // 下载完成移除元素
  window.URL.revokeObjectURL(href)
  return href
}
const exportLoading = ref(false)
// 导出
function handleExport() {
  exportLoading.value = true
  post(
    '/solution-ppm-work-order/api/v1/work_order/export',
    {
      ...state.filter,
      'pageSize': pagination.value.pageSize,
      'pageNo': pagination.value.current,
      'directionField': state.sort,
      status:activeKey.value
    },
    // {
    //     responseType: 'arraybuffer'
    // }
    {
      responseType: 'blob'
    }
  )
    .then(res => {
      // console.log(res)
      // if (res.type === 'application/octet-stream') {
      //
      // } else {
      //     message.info('下载失败')
      // }
      downloadExcel(res, '工单列表.xlsx')
    })
    .finally(() => {
      exportLoading.value = false
    })
}
//     搜索展开折叠
const filterExpand = ref(false)
function toggleFilterCollapse() {
  filterExpand.value = !filterExpand.value

  if(viewType.value==='卡片展示'){
    let body = document.querySelector('.gd-scroll-wapper')
    if (!filterExpand.value) {
      body.style.height = 'calc(100% - 260px)'
      headerOffset.value = 265
    } else {
      body.style.height = 'calc(100% - 360px)'
      headerOffset.value = 365
    }
  }  else{
    if (!filterExpand.value) {

      headerOffset.value = 265
    } else {
      headerOffset.value = 365
    }
  }

  calcTableHeight()
}
async function viewTypeChange(){
  console.log(viewType.value,'viewType.value');
  if(viewType.value==='卡片展示'){
   await nextTick()
    let body = document.querySelector('.gd-scroll-wapper')
    if (!filterExpand.value) {
      body.style.height = 'calc(100% - 260px)'
      headerOffset.value = 265
    } else {
      body.style.height = 'calc(100% - 360px)'
      headerOffset.value = 365

    }
  }
  handleSaveViewSetting(viewType.value)
}
// 设置显示设置
function handleSaveViewSetting(type){
  post('/solution-ppm-work-order/api/v1/work_order/person_config/create',{
    "check": type,
    "module": "WORK_ORDER_TABLE_OR_CARD"
  }).then(data=>{
    if(data.code!==200){
      message.error(data.message)
      return
    }
    message.success(data.message)
    getData()
  })
}
// 获取显示设置
function getViewSetting(){
  get('/solution-ppm-work-order/api/v1/work_order/person_config/search/WORK_ORDER_TABLE_OR_CARD').then(data=>{
    viewType.value = data.data?.check||'卡片展示'
  })
}
//     根因分析
const rootState = reactive({
  // 责任方
  responsibleParty: undefined,
  responsiblePartyList: [],
  // 业务类型
  businessType: undefined,
  businessTypeList: [],
  rootCauseClassifyList: undefined,
  rootCauseClassify: [],
  // 根因分析
  belongList: [],
  tagList: [],
  rootCauseFlag: false,
  tipVisible: false
})
const rootQuillEditor = ref(null)
// 获取责任方
function getResponsiblePartyList() {
  get(' /solution-ppm-basic-data/api/v1/dictionary/search/GD.ZRF').then(data => {
    rootState.responsiblePartyList = data.data
  })
}

// 根据责任方获取业务类型
function getBusinessTypeList() {
  let envId = rootState.responsiblePartyList.find(item => item.itemName === rootState.responsibleParty)?.itemCode
  console.log(envId)
  get(` /solution-ppm-basic-data/api/v1/dictionary/search/${envId}`).then(data => {
    rootState.businessTypeList = data.data
  })
}

// 根据业务类型获取根因分析
function getRootCauseClassifyList() {
  let envId = rootState.businessTypeList.find(item => item.itemName === rootState.businessType)?.itemCode
  get(` /solution-ppm-basic-data/api/v1/dictionary/search/${envId}`).then(data => {
    rootState.rootCauseClassifyList = data.data.map(item => {
      return {
        ...item
      }
    })
  })
}
// 保存切换前值
const preState = reactive({
  responsibleParty: undefined,
  businessType: undefined,
  rootCauseClassify: undefined
})

// 弹窗控制
const tipState = reactive({
  visible: false,
  pendingField: '', // 'responsibleParty' | 'businessType' | 'rootCauseClassify'
  nextValue: undefined
})

// 判断富文本是否有内容
function hasEditorContent() {
  const content = rootQuillEditor.value?.getText() || ''
  return content.trim().length > 0
}

// === 责任方 change ===
function responsiblePartyChange(nextVal) {
  if (hasEditorContent()) {
    tipState.visible = true
    tipState.pendingField = 'responsibleParty'
    tipState.nextValue = nextVal
    // 还原选择框临时值
    rootState.responsibleParty = preState.responsibleParty
    return
  }
  applyResponsiblePartyChange(nextVal)
}
function applyResponsiblePartyChange(val) {
  rootState.responsibleParty = val
  preState.responsibleParty = val
  rootState.businessType = undefined
  preState.businessType = undefined
  rootState.rootCauseClassify = undefined
  preState.rootCauseClassify = undefined
  clearEditor()
  getBusinessTypeList()
}

// === 业务类型 change ===
function businessTypeChange(nextVal) {
  if (hasEditorContent()) {
    tipState.visible = true
    tipState.pendingField = 'businessType'
    tipState.nextValue = nextVal
    rootState.businessType = preState.businessType
    return
  }
  applyBusinessTypeChange(nextVal)
}
function applyBusinessTypeChange(val) {
  rootState.businessType = val
  preState.businessType = val
  rootState.rootCauseClassify = undefined
  preState.rootCauseClassify = undefined
  clearEditor()
  getRootCauseClassifyList()
}

// === 根因分析 change ===
function rootCauseClassifyChange(nextVal) {
  if (hasEditorContent()) {
    tipState.visible = true
    tipState.pendingField = 'rootCauseClassify'
    tipState.nextValue = nextVal
    rootState.rootCauseClassify = preState.rootCauseClassify
    return
  }
  applyRootCauseClassifyChange(nextVal)
}
function applyRootCauseClassifyChange(val) {
  rootState.rootCauseClassify = val
  preState.rootCauseClassify = val
  const selected = rootState.rootCauseClassifyList.find(item => item.itemName === val)
  const description = selected?.description || ''
  setEditorText(description)
}

// === 弹窗确认 ===
function confirmRoot() {
  const field = tipState.pendingField
  const val = tipState.nextValue

  if (field === 'responsibleParty') {
    applyResponsiblePartyChange(val)
  } else if (field === 'businessType') {
    applyBusinessTypeChange(val)
  } else if (field === 'rootCauseClassify') {
    applyRootCauseClassifyChange(val)
  }

  tipState.visible = false
}

// 弹窗取消
function cancelRoot() {
  tipState.visible = false
}

// 清空富文本
function clearEditor() {
  rootQuillEditor.value?.setText('')
}

// 赋值富文本
function setEditorText(text) {
  nextTick(() => {
    rootQuillEditor.value?.setText(text)
  })
}
import { watchEffect } from 'vue'
// 初始赋值 preState
watchEffect(() => {
  preState.responsibleParty = rootState.responsibleParty
  preState.businessType = rootState.businessType
  preState.rootCauseClassify = rootState.rootCauseClassify
})
// 无需解决保存根因分析
function noNeedSaveRoot() {
  if (!resolvedData.value.parentId) {
    rootRef.value.validate().then(async () => {
      sonState.noNeedLoading = true

      const params = {
        responsibleParty: rootState.responsibleParty,
        businessType: rootState.businessType,
        rootCauseClassify: rootState.rootCauseClassify,
        rootCauseAnalysis: '',
        id: noNeedData.value.id
      }

      // === 单独处理 rootEditor 富文本图片上传 ===
      let rootDeltaContent = null
      try {
        rootDeltaContent = rootQuillEditor.value.getContents()
        const rootUploadTasks = rootDeltaContent.ops.map(async op => {
          if (op.insert?.image?.startsWith('data:')) {
            const file = dataURLtoFile(op.insert.image, 'image.png')
            const {
              data: { fullUrl }
            } = await uploadFileAPI(file)
            op.insert.image = fullUrl
          }
        })
        await Promise.all(rootUploadTasks)
        params.rootCauseAnalysis = JSON.stringify(rootDeltaContent)
      } catch (e) {
        console.error('处理 rootQuillEditor 出错：', e)
        // 同样不 return，继续提交
      }

      // === 提交接口 ===
      put('/solution-ppm-work-order/api/v1/work_order/root_cause_modify', params).then(data => {
        if (data.code !== 200) {
          message.error(data.message)
          sonState.noNeedLoading = true
          return
        }
        submitNoNeed()
      })
    })
  } else {
    submitNoNeed()
  }
}
function cancelRootMsg(){
  rootState.responsibleParty = rootState.businessType=rootState.rootCauseClassify = undefined
}
// 关注/取消关注
const followLoading = ref(false)
function handleFollow(item){
  item.followLoadng = true
  put(`/solution-ppm-work-order/api/v1/work_order/switch_follow/${item.id}`).then(data=>{
    if (data.code !== 200) {
      message.error(data.message)
      return
    }
    // item.follow = !item.follow  // 直接本地更新状态
    message.success(item.follow ? '已关注' : '已取消关注')
    getData()
  }).finally(()=>{
    item.followLoadng = false
  })
}
const activeKey = ref('未开始')
// 显示设置
const viewType = ref('卡片展示')
const gdColumns = ref(  [
  {
    title: '工单名称',
    dataIndex: 'content',
    align: 'center',
    ellipsis: true,
    resizable: true,
    width: 380,
    fixed: 'left',
  },
  {
    title: '优先级',
    dataIndex: 'priority',
    resizable: true,
    align: 'center',
    ellipsis: true,
    width: 80,
  },
  {
    title: '问题来源',
    dataIndex: 'questionSource',
    resizable: true,
    align: 'center',
    ellipsis: true,
    width: 120,
  },
  {
    title: '工单状态',
    dataIndex: 'status',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '工单类型',
    dataIndex: 'type',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '工单编号',
    dataIndex: 'number',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 150,
  },
  {
    title: '创建人（OWNER）',
    dataIndex: 'createdBy',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 150,
  },
  {
    title: '解决人',
    dataIndex: 'solver',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '项目经理',
    dataIndex: 'pmName',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: 'PMO',
    dataIndex: 'pmo',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '所属区域',
    dataIndex: 'areaName',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '所属客户',
    dataIndex: 'customer',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '所属项目',
    dataIndex: 'projectName',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '项目阶段',
    dataIndex: 'milepostName',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '所属任务',
    dataIndex: 'taskName',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '所属环境',
    dataIndex: 'environment',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '所属产品',
    dataIndex: 'production',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '版本',
    dataIndex: 'version',
    align: 'center',
    resizable: true,
    ellipsis: true,
    width: 120,
  },
  {
    title: '创建时间',
    dataIndex: 'createdTime',
    align: 'center',
    ellipsis: true,
    width: 150,
  },
  {
    title: '计划完成时间',
    dataIndex: 'endTime',
    align: 'center',
    ellipsis: true,
    width: 200,
  },
  {
    title: '实际完成时间',
    dataIndex: 'finishTime',
    align: 'center',
    ellipsis: true,
    width: 200,
  },
  {
    title: '操作',
    align: 'left',
    dataIndex: 'operation',
    width: 410,
    fixed: 'right'
  }
])
function getStatusColor(status) {
  return colorMap[status] || '#9DBAFF'
}
function handleResizeColumn(w, col) {
  col.width = w
}
</script>
<style lang="less" scoped>
.page_root {
  width: 100%;
  height: 100%;
  overflow: auto;
}
.page_root :deep(.@{ant-prefix}-spin-nested-loading),
.page_root :deep(.@{ant-prefix}-spin-container)
{
  height: 100%;
}
.page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper)
{
  display: flex;
  flex-flow: column nowrap;
  justify-content: flex-start;
}
.page_root :deep(.@{ant-prefix}-table)
{
  flex: auto;
  overflow: auto;
}
.table-moreBtn_down {
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis; width: 100px;
}

.table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
  background: #ebf1ff;
}

/*  表格树结构样式处理，展开按钮层级增加*/
:deep(.@{ant-prefix}-table-row-expand-icon) {
  z-index: 1;
}
/*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
:deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
  left: 15px !important;
  width: calc(100% - 15px);
}
:deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
  left: 30px !important;
  width: calc(100% - 30px);
}
:deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
  left: 45px !important;
  width: calc(100% - 45px);
}
:deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
  left: 60px !important;
  width: calc(100% - 60px);
}

/* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
:deep(.@{ant-prefix}-transfer-list)
{
  height: 100%;
  width: 50%;
}


.page_root {
  width: 100%;
  height: 100%;
  overflow: auto;
}
.page_root :deep(.@{ant-prefix}-spin-nested-loading),
.page_root :deep(.@{ant-prefix}-spin-container)
{
  height: 100%;
}
.page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper)
{
  display: flex;
  flex-flow: column nowrap;
  justify-content: flex-start;
}
.page_root :deep(.@{ant-prefix}-table)
{
  flex: auto;
  overflow: auto;
}
.table-moreBtn_down {
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis; width: 100px;
}

.table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
  background: #ebf1ff;
}

/*  表格树结构样式处理，展开按钮层级增加*/
:deep(.@{ant-prefix}-table-row-expand-icon) {
  z-index: 1;
}
/*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
:deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
  left: 15px !important;
  width: calc(100% - 15px);
}
:deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
  left: 30px !important;
  width: calc(100% - 30px);
}
:deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
  left: 45px !important;
  width: calc(100% - 45px);
}
:deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
  left: 60px !important;
  width: calc(100% - 60px);
}

/* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
:deep(.@{ant-prefix}-transfer-list)
{
  height: 100%;
  width: 50%;
}


/*样式*/
.page_root {
  overflow: hidden;
}
.body {
  height: 100%;
  background-color: #f0f2f5;
}
.top-search {
  margin-bottom: 16px;
  border-radius: 4px;
  display: flex;
  gap: 16px;
  justify-content: space-between;
}
.top-left {
  width: 100%;
  padding: 16px;
  background-color: #fff;
  border-radius: 4px;
}
.top-right {
  border-radius: 4px;
  background-color: #fff;
  padding: 20px 24px;
  padding-right: 36px;
}
.right-title {
  display: flex;
  margin-bottom: 8px;
}
.title-font {
  font-size: 14px;
  color: rgba(89, 89, 89, 0.65);
  letter-spacing: 0;
  text-align: center;
  font-weight: 400;
}

.top-search :deep(.ant3-col-6) {
  height: 32px;
}
.right-icon {
  display: flex;
}
.min-div,
.left-icon {
  width: 40%;
  display: flex;
  gap: 8px;
}
.max-div,
.right-icon {
  flex: 1;
}
.max-div {
  text-align: left;
}

.right-icon-content {
  flex: 1;
  display: flex;
  justify-content: space-between;
}
.ceycle,
.ceycle0,
.ceycle1,
.ceycle2,
.ceycle3 {
  width: 32px;
  height: 22px;
  color: #fff;
  text-align: center;
  line-height: 22px;
  font-weight: 600;
  font-style: oblique;
  letter-spacing: 1px;
}
.ceycle0 {
  background-color: #ff2a00;
}
.ceycle1 {
  background-color: #ffa940;
}
.ceycle2 {
  background-color: #ffa940;
}
.ceycle3 {
  background-color: #1890ff;
}

.s-bg-fff {
  background: #fff;
}
.status-progress{
  font-weight: 400;
}
.status-txt{
  flex: 1;
  color: #fff;
  text-align: left;
  box-sizing: border-box;
  padding-left: 7px;
  height: 22px;
  font-size: 14px;
}


/* 未开始 */
.status-wks {
  &.s-bg-color {
    background:#f2f6fc;
    color: #989898;
  }
  &.s-bg {
    background:#f2f6fc;
  }
  &.s-color {
    color: #A9A9A9;
  }
  &.s-border {
    border: 1px solid #A9A9A9;
  }
  &.s-border-left {
    border-left: 1px solid #A9A9A9;
  }
  &.s-border-top {
    border-top: 2px solid #A9A9A9;
  }
  &.s-bg-jb {
    background: linear-gradient(to  bottom,#f2f6fc, #ffffff);
  }
}

/* 已解决 */
.status-yjj {
  &.s-bg-color {
    background: #52C41A;
    color: #fff;
  }
  &.s-bg {
    background: #EDF9E8;
  }
  &.s-color {
    color: #52C41A;
  }
  &.s-border {
    border: 1px solid #52C41A;
  }
  &.s-border-left {
    border-left: 1px solid #52C41A;
  }
  &.s-border-top {
    border-top: 2px solid #52C41A;
  }
  &.s-bg-jb {
    background: linear-gradient(to  bottom, #EDF9E8, #ffffff);
  }
}

/* 解决中 */
.status-jjz {
  &.s-bg-color {
    background: #3875FF;
    color: #fff;
  }
  &.s-bg {
    background: #EBF1FF;
  }
  &.s-color {
    color: #3875FF;
  }
  &.s-border {
    border: 1px solid #3875FF;
  }
  &.s-border-left {
    border-left: 1px solid #3875FF;
  }
  &.s-border-top {
    border-top: 2px solid #3875FF;
  }
  &.s-bg-jb {
    background: linear-gradient(to  bottom, #EBF1FF, #ffffff);
  }
}

/* 无需解决 */
.status-wxjj {
  &.s-bg-color {
    background: #FFC900;
    color: #fff;
  }
  &.s-bg {
    background: #FFF8E0;
  }
  &.s-color {
    color: #FFC900;
  }
  &.s-border {
    border: 1px solid #FFC900;
  }
  &.s-border-left {
    border-left: 1px solid #FFC900;
  }
  &.s-border-top {
    border-top: 2px solid #FFC900;
  }
  &.s-bg-jb {
    background: linear-gradient(to  bottom, #FFF8E0, #ffffff);
  }
}

/* 已关闭 */
.status-ygb {
  &.s-bg-color {
    background: #262626;
    color: #fff;
  }
  &.s-bg {
    background: #EBEBEB;
  }
  &.s-color {
    color: #262626;
  }
  &.s-border {
    border: 1px solid #262626;
  }
  &.s-border-left {
    border-left: 1px solid #262626;
  }
  &.s-border-top {
    border-top: 2px solid #262626;
  }
  &.s-bg-jb {
    background: linear-gradient(to  bottom, #EBEBEB, #ffffff);
  }
}

/* 已回访 */
.status-yhf {
  &.s-bg-color {
    background: #9254DE;
    color: #fff;
  }
  &.s-bg {
    background: #EFE6FB;
  }
  &.s-color {
    color: #9254DE;
  }
  &.s-border {
    border: 1px solid #9254DE;
  }
  &.s-border-left {
    border-left: 1px solid #9254DE;
  }
  &.s-border-top {
    border-top: 2px solid #9254DE;
  }
  &.s-bg-jb {
    background: linear-gradient(to  bottom, #EFE6FB, #ffffff);
  }
}

/* 待分发 */
.status-dff {
  &.s-bg-color {
    background: #FF7D27;
    color: #fff;
  }
  &.s-bg {
    background: #FFEADC;
  }
  &.s-color {
    color: #FF7D27;
  }
  &.s-border {
    border: 1px solid #FF7D27;
  }
  &.s-border-left {
    border-left: 1px solid #FF7D27;
  }
  &.s-border-top {
    border-top: 2px solid #FF7D27;
  }
  &.s-bg-jb {
    background: linear-gradient(to  bottom, #FFEADC, #ffffff , #ffffff);
  }
}


.ph-icon,
.xc-icon,
.zj-icon {
  width: 72px;
  height: 22px;
  color: #262626;
  text-align: center;
  line-height: 22px;
  font-weight: 600;
  background-color: #fff;
}
.tip {
  display: inline-block;
  width: 60px;
  position: absolute;
  bottom: -20px;
  left: -20px;
  text-align: center;
}
.main {
  background-color: #fff;
  height: 100%;
  border-radius: 4px;
  padding: 20px 24px;
  padding-top: 16px;
  position: relative;
}
.main-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}
/*折叠面板样式*/

:deep(.ant3-collapse-header) {
  padding: 0 !important;
  border: none !important;
  color: #262626 !important;
}

:deep(.ant3-collapse-borderless > .ant3-collapse-item) {
  border-bottom: 1px solid #fff;
}

:deep(.ant3-collapse-borderless > .ant3-collapse-item > .ant3-collapse-content > .ant3-collapse-content-box) {
  padding: 0 !important;
}

:deep(.ant3-collapse-item) {
  //margin-bottom: 8px;
}

:deep(.ant3-collapse-icon-position-right > .ant3-collapse-item > .ant3-collapse-header) {
  color: #3875ff;
  background: #f0f2f5;
  position: relative;
}

/*折叠面板样式*/
.collapse-title {
  position: relative;
  width: 100%;
  display: flex;
  padding: 10px 16px;
  align-items: center;
  /* 如果需要保留左右两角的圆角，可以在这里添加 border-radius 样式 */
}
.title-border {
  border-bottom: 1px solid #d9d9d9;
}
.child-title {
  width: 100%;
  display: flex;
  justify-content: space-between;
  padding: 10px 24px;
  position: relative;
  border-bottom: 1px solid #d9d9d9;
}
.child-title::before {
  content: '';
  position: absolute;
  top: -1px;
  left: -1px;
  width: 0;
  height: 0;
  border-right: 20px solid transparent; /* 控制三角形的大小和方向 */
  border-top: 20px solid #ffa940; /* 三角形的颜色 */
  border-top-left-radius: 4px;
}
.collapse-title-left {
  display: flex;
  flex-direction: column;
  height: 49px;
  justify-content: space-between;
  align-items: center;
  padding-right: 16px;
  border-right: 1px solid #d9d9d9;
}
.left-flex{
  display: flex;
  width: 100%;
  box-shadow: 0 2px 6px #d3d8df;
}
.collapse-title-right {
  display: flex;
  align-items: center;
  gap: 16px;
}

.gd-title {
  font-size: 14px;
  color: #262626;
  letter-spacing: 0;
  font-weight: 500;
}
.collapse-title-font,
.inner-title {
  font-size: 14px;
  color: #595959;
  letter-spacing: 0;
  text-align: right;
  font-weight: 400;
}
.collapse-title-font {
  flex-shrink: 0; /* 不允许缩小，确保标题可见 */
}
.border-div {
  position: relative;
}
.border-line {
  position: absolute;
  width: 1px;
  height: 14px;
  background-color: #a5a6a7;
  right: -15px;
  top: 50%;
  transform: translate(-50%, -50%);
}
.collapse-title-right-btn {
  display: flex;
  gap: 8px;
}

.btn-item {
  position: relative;
  cursor: pointer;
}
.border-btn {
  position: absolute;
  width: 1px;
  height: 14px;
  background-color: #3875ff;
  right: -9px;
  top: 50%;
  transform: translate(-50%, -50%);
}
.active-btn {
  position: absolute !important;
  right: 20px !important;
  top: 58px !important;
  color: #3875ff !important;
  transform: translate(-50%, -50%) !important;
  font-size: 16px !important;
  font-weight: 500;
}
.active-icon {
  color: #3875ff;
  transform: rotate(90deg);
}
.item-inner {
  display: flex;
  padding: 7px 0;
  //background:#f2f6fc;
}

.item-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 7px 24px;
  border-right: 1px solid #d9d9d9;
  gap: 10px;
}

.item-content1,
.item-content2,
.item-content3,
.item-content4 {
  flex: 1; /* 平分宽度 */
}
.item-content4 {
  justify-content: start;
}
.inner {
  display: flex;
  justify-content: space-between;
}

.inner-title {
  text-align: right;
  flex: 0 0 auto; /* 保持标题宽度 */
}

.inner-msg {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1; /* 占用剩余空间 */
}
.inner-msg {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  height: 100%;
  flex: 1;
}
.inner-title {
  text-align: right;
}
.inner-main {
  display: flex;
  flex: 1;
}
.item-children {
  background: #f8f9fa;
  border: 1px solid #d9d9d9;
  margin-bottom: 16px;
  height: 93px;
}
.collapse-bottom {
  padding: 16px;
  padding-bottom: 0;
  background-color: #fff; /* 确保背景色 */
}

.item-children .collapse-title {
  padding-right: 16px;
  border-bottom: 1px solid #d9d9d9;
}
.child-inner {
  padding: 16px;
  display: flex;
  align-items: center;
  gap: 32px;
}
.item-children .inner-main {
  position: relative;
}
.item-children .border-line {
  position: absolute;
  width: 1px;
  height: 14px;
  background-color: #a5a6a7;
  right: -16px;
  top: 50%;
  transform: translate(-50%, -50%);
}
.pagination-div {
  position: absolute;
  right: 30px;
  bottom: 0;
  padding: 10px;
  background: transparent; /* 可选：为背景添加颜色 */
}
.form-content :deep(.ant3-form-item-label) {
  width: 105px;
}
.form-content :deep(.ant3-input-number),
:deep(.ant3-picker) {
  width: 100%;
}
:deep(.ql-toolbar) {
  background: #fafafa;
  border: 1px solid #d9d9d9;
}
:deep(.ql-blank) {
  min-height: 110px;
  background: #ffffff;
}
:deep(.ql-editor) {
  min-height: 110px;
  background: #ffffff;
}
.remarks-modal {
  background: #ffffff;
  border: 1px solid #d9d9d9;
  height: 140px;
}
.change-status :deep(.ant3-form-item-label) {
  width: 110px;
}
.tip {
  font-weight: 800;
}
.father-right {
  max-width: 100%; /* 限制宽度 */
  flex: 1;
  padding-left: 13px;
  padding-right: 18px;
  display: flex;
  overflow: hidden;
  flex-direction: column;
}
.father-left {
  overflow: hidden;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  margin-bottom: -4px;
}

.gd-item:hover{
  .father-last {
    display: flex;
  }
}

.father-last {
  display: flex;
  gap: 18px;
  align-items: center;
  .last-left {
    display: flex;
    gap: 10px;
    .last-top-btn,
    .last-bottom-btn {
      border-right: 1px solid #aaa ;
      padding: 0;
      padding-right:10px;
      display: flex;
      gap: 8px;
      height: 10px;
      overflow: visible;
      align-items: center;
      margin-top: 15px;
      margin-bottom: 10px;

    }
    .last-bottom-btn {
      padding-right:18px;
    }

  }
  .last-right {
    display: flex;
    align-items: center;
    gap: 8px;
    justify-content: space-around;
    margin-top: 4px;
    height: 10px;
    &.detail{
      border-left: 1px solid #aaa;
      padding-left: 18px;
    }
  }
}
.father-title {
  display: block; /* 确保其为块级元素 */
  max-width: 100%; /* 确保宽度有限制 */
  font-size: 15px;
  color: #262626;
  letter-spacing: 0;
  font-weight: 600;
  white-space: nowrap; /* 禁止换行 */
  overflow: hidden; /* 隐藏溢出内容 */
  text-overflow: ellipsis; /* 显示省略号 */
  &.tit-kuo{
    margin-left: -6px;
  }
}

.father-bottom {
  display: flex;
  align-items: end; /* 容器垂直底部对齐 */
  gap: 8px;
  justify-content: space-between;
  margin-top: 4px;
  opacity: .6;
}
.father-bottom > * {
  align-self: flex-end; /* 内部元素底部对齐 */
}
.father-bottom-left {
  display: flex;
  gap: 30px;
  white-space: nowrap; /* 确保整体不换行 */
  overflow: hidden; /* 防止溢出 */
}
.father-icon {
  font-size: 12px;
  color: #333333;
  position: relative;
  top: -1px;
  margin-right: 4px;
}
.father-bgc1 {
  display: inline-block;
  width: 13px;
  height: 13px;
  background-size: cover;
  position: relative;
  top: 1px;
  margin-right: 4px;
}
.father-bgc2 {
  display: inline-block;
  width: 13px;
  height: 13px;
  background-size: cover;
  position: relative;
  top: 1px;
  margin-right: 4px;
}
.father-bgc3 {
  display: inline-block;
  width: 13px;
  height: 13px;
  background-size: cover;
  position: relative;
  top: 1px;
  margin-right: 4px;
}
:deep(.ant3-collapse-item) {
  background: #ffffff;
}
.collapse-title-right .border-line {
  right: -8px;
}
.gd-scroll-wapper{
  position: relative;
  height: calc(100% - 260px);

}
.gd-scroll {
  overflow-y: auto;
  overflow-x: hidden;
  height: 100%;
  position: relative;
  z-index: 1;
}
.gd-scroll-bar{
  opacity: .9;
  position: absolute;
  right: 3px;
  width: 9px;
  overflow: hidden;
  z-index: 0;
  display: flex;
  flex-direction: column;
  top:0;
  bottom:0;
  gap:1px;
  .gd-bar-item{
    flex:1;
    cursor: pointer;
    &.status-all{
      border-left: 3px solid #aaa;
      &.status-解决中{
        border-left: 3px solid #3875FF;
      }

      &.status-已解决,
      &.status-无需解决,
      &.status-已关闭,
      &.status-已回访 {
        border-left: 0 solid transparent;
      }
    }
  }
  .gd-bar-item.item-open{
    flex:2
  }
  .ceycle{
    font-size: 0 !important;
    width: 100px;
    height: 100% !important;
    flex: 1;
    line-height: unset !important;
  }
}
.gd-item {
  margin-bottom: 24px;
}
.gd-item:last-child {
  margin-bottom: 5px;
}
.solution-div {
  background: rgba(56, 117, 255, 0.1);
  padding: 0 16px;
  padding-bottom: 16px;
}
.inner-solution {
  display: flex;
  justify-content: start;
}
.top-title {
  height: 16px;
  padding-left: 8px;
  border-left: 4px solid #3875ff;
  font-size: 16px;
  line-height: 16px;
  color: #262626;
  font-weight: 600;
}
.top-tip {
  font-size: 12px;
  letter-spacing: 0;
  text-align: justify;
  font-weight: 400;
  color: #ff8022;
  background: rgb(250 100 0 / 5%);
  padding: 6px 16px;
  margin-right: 8px;
}
.description-tip {
  font-size: 12px;
  color: #262626;
  letter-spacing: 0;
  text-align: center;
  font-weight: 400;
  color: #ff8022;
  background: rgb(250 100 0 / 5%);
  padding: 6px 16px;
  margin-bottom: 16px;
}
.tip-img {
  width: 16px;
  height: 16px;
  color: #ff8022;
}
.file-content {
  padding: 16px;
  color: #3875ff;
  cursor: pointer;
}
.form-content :deep(.ql-snow .ql-editor) img {
  width: 200px;
}
.change-status :deep(.ql-snow .ql-editor) img {
  width: 200px;
}
.collapse-content-font {
  font-size: 14px;
  color: #262626;
  letter-spacing: 0;
  font-weight: 400;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex-grow: 1; /* 让内容占满可用空间 */
  min-width: 0; /* 处理 flex 子项溢出问题 */
}
.max-length {
  display: inline-block; /* 使得元素能够处理 overflow */
  max-width: 180px; /* 根据需要调整最大宽度 */
  overflow: hidden; /* 隐藏超出部分 */
  white-space: nowrap; /* 不换行 */
  text-overflow: ellipsis; /* 显示省略号 */
}

:deep(
                  .ant3-collapse .ant3-collapse-item-disabled > .ant3-collapse-header,
                  .ant3-collapse .ant3-collapse-item-disabled
              ) {
  cursor: default;
}
.remove-icon :deep(.ant3-select-selection-item-remove) {
  display: none !important;
}
.lz-img,
.zgd-img {
  height: 18px;
  width: 18px;
  background-size: cover;
}
/*工单SOP*/
.modal-table :deep(.@{ant-prefix}-table-thead) > tr > th {
  background: #3875ff;
  font-size: 14px;
  font-family: arial, helvetica, 'microsoft yahei';
  font-weight: 600;
  color: #ffffff;
  border-bottom: 1px solid #3875ff;
  padding: 8px 16px;
}
.modal-table :deep(.table-striped-odd) td {
  background-color: #ffffff;
}
.modal-table :deep(.table-striped-even) td {
  background-color: #f8fafc;
}
.modal-table :deep(.@{ant-prefix}-table-tbody) tr > td {
  font-size: 14px;
  font-family: arial, helvetica, 'microsoft yahei';
  font-weight: 400;
  color: #262626;
  padding: 8px 16px;
  word-break: break-all;
  R .cell-wrapper {
    padding: 0 16px;
  }
}
.sop-start-tip {
  height: 40px;
  padding: 12px 16px;
  background: rgba(250, 173, 20, 0.1);
  display: flex;
  font-size: 14px;
  color: #262626;
  font-weight: 400;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
}
.change-status-tip {
  height: 52px;
  line-height: 52px;
  font-size: 14px;
  color: #262626;
  font-weight: 400;
}
.no-need-tip {
  display: flex;
  padding: 10px 16px;
  background: rgba(250, 173, 20, 0.1);
  font-size: 14px;
  color: #262626;
  font-weight: 400;
  gap: 8px;
  margin-bottom: 16px;
  align-items: center;
}
.modal-sop-title {
  height: 16px;
  line-height: 16px;
  padding-left: 8px;
  border-left: 4px solid #3875ff;
  font-size: 16px;
  color: #262626;
  letter-spacing: 0;
  font-weight: 600;
  margin-bottom: 16px;
}
.resolved-div {
  display: flex;
  padding: 10px 16px;
  background: rgba(250, 173, 20, 0.1);
  font-size: 14px;
  color: #262626;
  font-weight: 400;
  gap: 8px;
  margin-bottom: 16px;
}
.change-status-resolved {
  display: flex;
  gap: 16px;
}

.derivative-div-no {
  position: absolute;
  right: 0;
  top: 0;
  color: #595959;
  background: #dedede;
  border-radius: 0 4px 0 4px;
  height: 22px;
  width: 64px;
  line-height: 22px;
  font-size: 12px;
  text-align: center;
}
.ant-dropdown-link {
  color: #3875ff;
}
.timeout {
  position: absolute;
  right: 0;
  top: 0;
  width: 50px;
  height: 22px;
  line-height: 22px;
  background: #ff2a00;
  border-radius: 0 4px 0 4px;
  color: #fff;
  text-align: center;
  font-size: 12px;

}

.derivative-div {
  position: absolute;
  right: 0px;
  top: 0;
  background: #ccf1ff;
  color: #00b8ff;
  border-radius: 0 4px 0 4px;
  height: 22px;
  width: 64px;
  line-height: 22px;
  text-align: center;
  font-size: 12px;

}
.toggle-div {
  display: flex;
  padding-right: 12px;
}
.top-search :deep(.ant3-col) {
  height: 48px;
}
.top-left {
  padding-bottom: 0;
}
.gd-scroll::-webkit-scrollbar {
  width: 15px !important; /* 垂直滚动条宽度 */
  height: 15px !important; /* 水平滚动条高度 */
  cursor: pointer;
}

.gd-scroll::-webkit-scrollbar-track {
  background: transparent !important;
  border-radius: 0px !important;
}

.gd-scroll::-webkit-scrollbar-thumb {
  background: rgba(0,0,0,.4s) !important;
  border-radius: 0 !important;
}

.gd-scroll::-webkit-scrollbar-thumb:hover {
  background: rgba(0,0,0,.6) !important;
}
.under-line:hover {
  color: #3875ff;
  cursor: pointer;
  text-decoration: underline;
}


/*工单SOP*/
/*无需解决加新功能*/
.no-need-form :deep(.ant3-form-item-label){
  width: 80px;
}
.gd-table-box :deep(.@{ant-prefix}-table-tbody) tr > td {
  font-size: 14px;
  font-weight: 400;
  color: #262626;
  border-bottom: 1px solid #d9d9d9;
  padding: 8px 16px;
  word-break: break-all;
}
.table-gd-name{
  display: flex;
  height: 20px;
  justify-content: start;
  gap: 8px;
  align-items: center;
  color: #262626;
  font-weight: 600;
}
.ellipsis-div{
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 180px;
}
.timeout-table {
  width: 50px;
  height: 22px;
  line-height: 22px;
  background: #ff2a00;
  border-radius: 0 4px 0 4px;
  color: #fff;
  text-align: center;
  font-size: 12px;
  flex-shrink: 0;

}
.status-tag {
  font-size: 14px;
  color: #fff;
  letter-spacing: 0;
  text-align: center;
  line-height: 22px;
  font-weight: 500;
  width: 55px;
  height: 22px;
  border-radius: 2px;
  margin: 0 auto;
}
</style>
